C语言中的“静态”、“全局”的概念很容易弄混淆,无论是在学校,还是工作了以后,我个人在写代码的时候能避开就避开,咋一看还以为是优良的编程习惯呢,实际上是因为对C语言的不完全掌握, 相信也有一些人跟我一样,对static与extern也是非常的不愿提及。尽管各式各样的编程规范里都要求我们尽量不要使用全局变量,注意措辞,是“尽量”,这说明有的时候还是避免不了的,而静态变量就不必说了。
对一门编程语言的理解有点像打扫房间,你越不愿意扫的角落越容易引起你的不安。因此,很有必要把这里好好的“打扫”一下。下面的文字有些来自网络,来自书本,还有就是是个人的体会,而且每一个结论都用了一些实验验证了。
先说说静态修饰的涵义:静态修饰的意义主要体现在一次存储和作用域限定;
1、 一次存储:静态修饰的一次存储功能主要体现在变量上
a) 静态局部变量只被初始化一次,下一次初始化根据上一次的结果值,有点类似于c++中类的静态成员变量,即无论该类型生成多少个实例对象,所有的对象共用一个静态变量,到这里就是无论这个函数调用多少次,该静态变量只初始化一次,并没有因为超出其生存期而被销毁,只是外部不可见而已,用个例子说明之:
void fun1( int v ) { static int value = v; static int value = v; } int main( int arc, char *args[ ]) { fun1( 50 ); fun1( 100 ); } |
执行的结果是:value : 50 value : 50
说明在第二次调用fun1( )时的初始化value的采用的是上一次value的值,value在静态区的存储空间并没有因为fun1( )的结束而被释放,即体现了一次存储;
b) sdf
2、 作用域限定:静态修饰的作用域限定功能同时体现在函数与变量上;
a) 对于函数而言,任何用static修饰的函数,其作用域仅为当前源文件,而对外部来说这个函数是不可见的,即只有和其在同一源文件中的函数才能调用这个静态函数;反过来说,如果一个函数仅仅被同一源文件中的其他函数调用,那么这个函数应该声明为静态的,这样做的好处在于:可以一定程度上的解决不同源文件之间函数的命名冲突问题;
b) 对于变量而言,static修饰的全局变量,只在当前源文件中有效,对外部不可见,外部文件不能够引用;
接下来分析一下全局变量以及全局变量与静态变量的关系:
顾名思义,全局变量是指能够在全局引用的变量,相对于局部变量的概念,也叫外部变量;同静态变量一样,全局变量位于静态数据区,全局变量一处定义,多处引用,用关键字“extern”引用“外部”的变量。
全局变量也可以是静态的,在前面有过说明,静态全局变量的意义就是不让“外部”引用,是单个源文件里的全局变量,即是编译阶段的全局变量,而不是连接阶段的全局变量。
通过上面的分析,我们不难得出以下结论:
1、 静态函数与普通函数的区别在于:静态函数不可以被同一源文件以外的函数调用。
2、 静态局部变量与普通局部变量的区别在于:静态局部变量只初始化一次,下一次初始化实际上是依然是上一次的变量;
3、 静态全局变量与普通全局变量的区别在于:静态全局变量的作用域仅限于所在的源文件。
补充:如果在头文件中如果定义一个静态全局变量(不太好的习惯,很少的时候需要这样做),那意味着每一个包含此头文件的源码文件里都会包含这样一个相互独立的全局变量。