1. 前言:staticC/C++中一个很重要的关键字,最近阅读了很多博客和资料,遂在此对自己的学习笔记进行简单的总结并发表在这里

一、C语言中的static

• 静态全局变量:在全局变量之前加上关键字static,该全局变量就被定义成了一个静态全局变量

特别注意:

1.静态全局变量在内存中的存储位置:静态区(全局区)。 [注]:静态区(全局区)在整个程序运行期间都存在

2.静态全局变量的初始化:未经初始化的静态全局变量会被程序自动初始化为0。 [注]:在C语言中,未经初始化的全局变量的值是任意的;而在C++中,未经初始化的全局变量也会被程序自动初始化为0

3.全局变量和静态全局变量的存储方式是一样的,但不同的是全局变量在整个源代码中都是可以使用的,而静态全局变量只能在当前文件中使用。比如一个程序有3个文件a.cpp、b.cpp和c.cpp,如果在文件a.cpp中定义了一个全局变量x,那么变量x在文件a.cpp、b.cpp和c.cpp中都可以使用;但如果在文件a.cpp中定义了一个静态全局变量y,那么变量y只能在文件a.cpp中使用文件b.cpp和文件c.cpp都不可以使用该静态全局变量y

源文件file1.cpp:

  1. // 文件file1.cpp
  2. int value1=;//全局变量value1
  3. static int value2;//静态全局变量value2,默认初始化为0
  4. ......

 源文件file2.cpp:

  1. // 文件file2.cpp
  2. extern int value1; //成功:期望使用文件file1中定义的全局变量value1
  3. extern int value2; //错误:期望使用文件file1中定义的静态全局变量value2,但value2是static类型,只能在file1中使用,无法被其他文件使用
  4. ......

4.使用静态全局变量的好处:

a.将一个全局变量定义为静态全局变量,相当于让该全局变量对该程序的其他源文件进行了“隐藏”,也就是说该静态全局变量只能在定义它的源文件中使用,而程序的其他源文件则无法访问该变量

b.程序中的其他源文件中可以使用与该静态全局变量同名的变量,而不会发生冲突

5.在C/C++程序中,如果一个全局变量仅仅在单个源文件中使用,则可以将该全局变量修改为静态全局变量,以降低模块间的耦合度


• 静态局部变量:在局部变量之前加上关键字static,该局部变量就被定义成了一个静态局部变量

特别注意:

1.静态局部变量在内存中的存储位置:静态区(全局区)。[注]:普通局部变量在内存中的存储位置为栈区

2.静态局部变量的初始化:未经初始化的静态局部变量会被程序自动初始化为0。[注]:在C/C++中,未经初始化的普通局部变量值是任意的

3.static并没有改变局部变量的作用域。换句话说就是静态局部变量的作用域仍是局部作用域,当定义它的函数或语句块结束的时候,其作用域也就随之结束。 [注]:与之相反,static改变了全局变量的作用域(在声明它的文件之外是不可见的)

4.static虽然没有改变局部变量的作用域,但它改变了局部变量在内存中的存储位置(而static修饰的全局变量在内存中的存储位置则没有被static改变),即从原来的栈区中存放改变为静态区(全局区)中存放。因此静态局部变量在离开其作用域时,并没有像一般局部变量那样被销毁,而是仍驻留在内存中的静态区(全局区)中,直到程序结束,只不过在其离开自己的作用域时,我们无法再对其进行访问

  1. #include<iostream>
  2. using namespace std;
  3. int count=;
  4. int fun(){
  5. static int count=;
  6. return count--;
  7. }
  8. int main(){
  9. cout<<"Global\tLocal Static"<<endl;
  10. for(int i=;i<=;i++){
  11. cout<<" "<<count++<<"\t "<<fun()<<endl;
  12. }
  13. return ;
  14. }

5.在C/C++中,如果全局变量仅有单个函数访问,则可以将该全局变量改为该函数的静态局部变量,以降低模块间的耦合度


 • 静态函数:在函数的返回值类型前加上关键字static,该函数就被定义成了一个静态函数

特别注意:

1.和静态全局变量相似,静态函数只能在声明它的源文件中可见,而不能被该程序的其他源文件所使用。

源文件file1.cpp:

  1. //文件file1.cpp
  2. ......
  3. extern void fun1(){......} //定义函数fun1
  4. static void fun2(){......} //定义静态函数fun2
  5. ......

源文件file2.cpp:

  1. //文件file2.cpp
  2. ......
  3. extern void fun1();//成功:期望使用文件file1.cpp中的函数fun1
  4. extern void fun2();//错误:期望使用文件file1.cpp中的静态函数fun2,但fun2是static类型函数,只能在file1中使用,无法被其他文件使用

2.使用静态函数的好处:

a.在该程序的其他源文件中可以定义和使用与该静态函数同名的函数,而不会发生冲突

b.将一个普通函数定义为函数,相当于让该函数对该程序的其他源文件进行了“隐藏”,也就是说该静态函数只能在定义它的源文件中使用,而程序的其他源文件则无法调用该函数

c.静态函数会被自动分配在一个一直使用的存储区域,直到程序结束。这样避免了普通函数在调用时的进栈出栈操作,从而提高程序的运行速度


• 总结:static在C语言中的作用:

——隐藏功能:static修饰的全局变量和普通函数只能在定义它们的源文件中使用,相当于对程序中的其他源文件进行了隐藏

——默认初始化功能:static修饰的变量,不管是全局变量还是局部变量,在用户没有显式初始化它们的条件下,系统都会将他们默认初始化为0

——延长“寿命”功能:static修饰的局部变量存储在内存的静态区(全局区)而非栈区,而静态区中存储的内容只会在程序结束时被OS释放,因此当static修饰的局部变量离开自己的作用域时,其不会像一般局部变量那样被系统销毁,而是一直驻留在系统的内存中,直到程序结束。


二、C++中的static

• 静态数据成员:自定义类中被static修饰的成员变量

特别注意:

1.静态数据成员在内存中的存储位置:静态区(全局区)

2.使用:

  1. 语法:类名::静态数据成员名

 3.静态数据成员属于类换句话说就是类的静态数据成员为其所有对象所共享,不管该类有多少对象,静态数据成员只有一份存储于公共的内存中

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Student{
  5. public:
  6. static int count;//记录该类的对象的个数
  7. Student(){
  8. count++;
  9. }
  10. Student(string name,int age):Name(name),Age(age){
  11. count++;
  12. }
  13. ~Student(){
  14. count--;
  15. }
  16. private:
  17. string Name;
  18. int Age;
  19. };
  20. 20 int Student::count=0; //对count进行初始化
  21. int main(){
  22. Student stu1("Tomwenxing",);
  23. Student stu2("Ellen",);
  24. Student stu3("Jack",);
  25. cout<<"Student类的对象的个数:"<<Student::count<<endl;
  26. return ;
  27. }


 • 静态成员函数:自定义类中被static修饰的成员函数

 特别注意

1.在C++的自定义类中,一个常规的成员函数声明往往意味着:

  • 该成员函数能够访问其所在类的私有部分

  • 该成员函数位于其所在类的作用域之中

  • 该成员函数必须由一个对象去激活从而被调用(通过this指针来实现)

如果将该类的一个成员函数声明为static,则可以只让它拥有前两种性质

2.使用:

  1. 语法1:类名::静态成员函数名
  2. 语法2:对象名.静态成员函数名

3.和静态数据成员一样,静态成员函数也属于类,类的静态成员函数为其所有对象所共享。

4.类中的普通成员函数既可以访问一般成员变量,也可以访问静态数据成员;而类中的静态成员函数只能访问类中的静态数据成员。

[解释]:编译器在编译程序中的自定义类时,会在类中的每个普通成员函数中插入this指针,而对static修饰的静态成员函数则不会插入this指针。由于静态成员函数中没有this指针,因此静态成员函数无法在其函数体内访问非静态数据成员;相反,由于静态数据成员属于类而非特定对象,故不需要this指针也可以在函数体内访问静态数据成员,因此不管是普通成员函数还是静态成员函数,都可以在其函数体内访问静态数据成员。

5.同理,普通成员函数中可以调用静态成员方法,而静态成员方法中不能调用普通成员函数

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Student{
  5. public:
  6. static int count; //静态数据成员
  7. Student(){
  8. count++;
  9. }
  10. Student(string name,int age):Name(name),Age(age){
  11. count++;
  12. }
  13. ~Student(){
  14. count--;
  15. }
  16. void show1();
  17. static void show2();
  18. private:
  19. string Name;
  20. int Age;
  21.  
  22. };
  23. int Student::count=0; //对count进行初始化
  24. /*
  25. 25 编译器对成员函数show1的改写:
  26. 26 void Student::show1(Student* const this){
  27. 27 cout<<"Name:"<<this->Name<<endl;
  28. 28 cout<<"Age:"<<this->Age<<endl;
  29. 29 cout<<"Count:"<<count<<endl;
  30. 30 show2();
  31. 31 */
  32. void Student::show1(){
  33. cout<<"调用了方法show1"<<endl;
  34. cout<<"Name:"<<Name<<endl;
  35. cout<<"Age:"<<Age<<endl;
  36. cout<<"Count:"<<count<<endl;
  37. show2();//在普通成员函数中调用静态成员函数
  38. }
  39. void Student::show2(){ //编译器不会为静态成员函数添加this指针
  40. cout<<"调用了方法show2"<<endl;
  41. 41 //cout<<"Name:"<<Name<<endl; //错误:静态成员函数不能访问非静态数据成员
  42. 42 //cout<<"Age:"<<Age<<endl; //错误:静态成员函数不能访问非静态数据成员
  43. 43 //show1(); //错误:静态成员函数中不能调用普通成员函数 (只能以this->show1()的形式调用)
  44. cout<<"Count:"<<count<<endl;
  45. }
  46. int main(){
  47. Student stu1("Tomwenxing",);
  48. Student stu2("Ellen",);
  49. Student stu3("Jack",);
  50. stu3.show1();
  51. cout<<"----------分界线----------------"<<endl;
  52. stu2.show2();//可以通过对象来调用静态成员函数
  53. cout<<"----------分界线----------------"<<endl;
  54. Student::show2() ;//也可以通过类来调用静态成员函数
  55. return ;
  56. }

C/C++:static用法总结的更多相关文章

  1. 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  2. 四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  3. C语言中static用法介绍

    C语言中static用法介绍     对于新手来说,很多东西的用法还不是很清楚,我们今天一起来看看C语言中static用法介绍     1.声明了static的变量称为静态变量,根据作用域的不同又分为 ...

  4. static用法总结

    C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 一.面向过程设计中的st ...

  5. c++ static用法总结【转载】

    static关键字是C, C++中都存在的关键字.static从字面理解,是“静态的“的 意思,与此相对应的,应该是“动态的“. static的作用主要有以下3个: 1.扩展生存期: 2.限制作用域: ...

  6. (转-经典-数据段)C++回顾之static用法总结、对象的存储,作用域与生存期

    转自:https://blog.csdn.net/ab198604/article/details/19158697相关知识补充:https://www.cnblogs.com/rednodel/p/ ...

  7. c/c++中static用法总结

    static的作用主要有两种: 第一个作用是限定作用域:第二个作用是保持变量内容持久化: c语言中static的用法: 1.全局静态变量: 用法:在全局变量前加上关键字static,全局变量就定义成一 ...

  8. 【C++初级】static用法总结、问题探讨及常见错误排查

    static的基本用法: static的作用主要有两种第一个作用是限定作用域:第二个作用是保持变量内容持久化: 一.c语言中static的用法: 1.全局静态变量: 用法:在全局变量前加上关键字sta ...

  9. java中静态代码块的用法 static用法详解和static静态导入

    (一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...

  10. C/C++ static用法

    这篇文章没有太多的实际内容,简单记录下static的用法.顺便试一下用markdown来写文章. 1. 在函数中使用 我们都知道在一个函数中的变量是存储在栈区中,函数的每一次调用都伴随着变量的重新定义 ...

随机推荐

  1. [图解tensorflow源码] Session::Run()流程图 (单机版)

  2. 网络编程中的read,write函数

    关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illustrated,vol1>(TCP/IP详解卷1). 关于第二层面,依然建议Richard Steve ...

  3. 06_Java基础语法_第6天(自定义类、ArrayList集合)_讲义

    今日内容介绍 1.自定义类型的定义及使用 2.自定义类的内存图 3.ArrayList集合的基本功能 4.随机点名器案例及库存案例代码优化 01引用数据类型_类 * A: 数据类型 * a: java ...

  4. PHP切割字符用到的explode 以及计数count

    在thinkphp中同样可以用 explode来进行字符的切割工作,比如 $jihe='1,2,3,4'; 在使用explode之后,可以获得一个数组: $array=explode(',',$jih ...

  5. Docker vs Warden

    相同点: 都是依赖宿主操作系统内核的轻量级容器: 都采用了linux内核技术实现容器隔离(namespace)和资源限制(cgroup): 都使用了aufs文件系统: 不同点: 用途 warden是C ...

  6. An Introduction to the Basics of Modern CSS Buttons

    https://www.sitepoint.com/modern-css-buttons/

  7. Openstack入门篇(十)之nova服务(计算节点)的部署与测试

    1.安装服务软件包 [root@linux-node2 ~]# yum install -y centos-release-openstack-newton [root@linux-node2 ~]# ...

  8. iOS开发者证书-详解

    iOS开发者证书-详解/生成/使用 本文假设你已经有一些基本的Xcode开发经验, 并注册了iOS开发者账号. 相关基础 加密算法 现代密码学中, 主要有两种加密算法: 对称密钥加密 和 公开密钥加密 ...

  9. REST API 开发

    本文我们将使用Spring MVC 4实现 CRUD Restful WebService , 通过RestTemplate写一个 REST 客户端,定义这些服务. 我们也可以通过外部的一些客户端来测 ...

  10. Python面向对象之封装、property特性、绑定方法与非绑定方法

    一.封装 ''' 1.什么封装 封:属性对外是隐藏的,但对内是开放的(对内是开放的是因为在类定义阶段这种隐藏已经发生改变) 装:申请一个名称空间,往里装入一系列名字/属性 2.为什么要封装 封装数据属 ...