一、总述
由于C++兼容C语言,所以static在C语言中的用法对于C++是同样适用的。两者的不同就是C++中多出来的特性,而这些特性与C++面线对象的特性有关。
二、static在C语言中的作用(C++通用)
1、修饰变量
a、修饰全局变量(全局变量与静态全局变量的对比)
- 修饰全局变量:作用域仅限于变量被定义的文件中,其他文件即使用extern声明也无法直接使用此变量,extern用法详见这里。(可以间接访问,即通过本文件的非static函数返回static变量的值,类似于C++类中的private变量外界没有权限访问,但是可以通过public函数返回private变量的值)。
- 全局变量和全局静态变量对比:全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同,且都只初始化一次,但静态全局变量对其他文件不可见,全局变量是可见的。(静态存储和动态存储详见静态存储、动态存储、静态变量与动态变量)
- 总结:把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
b、修饰局部变量
- 修饰局部变量:在函数内定义的局部变量被修饰,可以延长变生命周期,但是作用域不变,只初始化一次。
- 局部变量与局部静态变量对比:普通局部变量定义后,出了作用域就会被释放,静态局部变量生命周期到程序结束才结束。
- 总结:把局部变量改变为静态变量后是改变了它的存储方式,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
2、修饰函数
和全局变量一样,函数的定义和声明默认情况下是extern的,也就是说可以在其他文件访问,但静态函数只是在声明它的文件当中可见,不能被其他文件所用。
三、static在C++中的作用
C+ +重用了这个关键字,并赋予它与前面不同的含义:表示属于一个类,而不是属于此类的任何特定对象的变量和函数。
1、静态数据成员.
静态数据成员是属于整个类的,而不是属于某个对象。即不管实例多少个对象,它们都公用一个静态数据成员(如:使用静态数据成员统计类已经实例化了多少对象)。
在c++中,普通数据成员在构造函数的函数体或初始化表中初始化;常量数据成员(const int a )必须在构造函数的初始化表中初始化(const对象或引用只能初始化但是不能赋值,而构造函数的函数体内只能做赋值而不是初始化);而静态数据成员(static int b )则必须在类外初始化(int 类名::b=100),这是因为静态数据成员不属于任何一个对象,而是属于整个类的。
2、静态成员函数
静态成员函数是属于整个类的,而不是属于某个对象。静态成员函数可以被该类的所有对象直接访问;静态成员函数本身只能访问静态成员,不可以访问非静态成员。
四、常见面试题--为什么static变量值只初始化一次?
对于所有的对象(不仅仅是静态对象),初始化都只有一次,而由于静态变量具有“记忆”功能,初始化后,一直都没有被销毁,都会保存在内存区域中,所以不会再次初始化。存放在静态区的变量的生命周期一般比较长,它与整个程序“同生死、共存亡”,所以它只需初始化一次。而auto变量,即自动变量,由于它存放在栈区,一旦函数调用结束,就会立刻被销毁。