当前位置:编程学习 > C/C++ >>

C++ static ,extern以及全局变量之间的相关逻辑

全局变量,就是指那些定义在函数之外的变量,当然也是定义与类之外的变量。
(1)全局变量会被自动初始化,函数中的变量不会被自动初始化,类中定义的那些成员变量(内建)也不会自动初始化。那么这里有一个疑问,为什么要这样设置?并且为什么,进程内存区中,分为初始化了的全局变量和静态变量,和未初始化的全局和静态变量。
(2)全局变量如果加上static关键字,事情将会变得很奇妙。
我们知道,全局变量理论上是指应用程序级别的全局。普通的全局变量是面向整个程序的,当各个文件各自编译,然后链接成一个可执行程序之后,全局变量的确是被所有文件中的“看到的”,但是,如果想让别的文件在编辑程序的是否就能够看到,(如果你不做然后措施,直接使用另外一个文件中定义的变量,那将通不过编译)
有两个办法:
第一个就是#include方法,但是这个方法,其实是将文件合并成一个文件,并没有正面回答。
第二个就是在要使用该变量的文件中声明(extern)一个外部变量,这样等于就是告诉编译器,“该变量是有的,只是在另外一个文件中,等到链接的时候你就可以看到了。”这个extern必须要加,否则就是重新定义个变量,到时候连接会出现重定义问题。
但是,如果你在全局变量前加上static,那么它的作用范围就变小了,编程了文件范围。这就会导致该变量是不容许别的文件通过extern声明方式来操作。因为该变量对其它文件是不可见的。
我们所说的变量的生命周期和作用域时我们有这样的说法:
1) 全局变量和静态变量的生命周期为整个进程,他们都处在内存的同一个区域
2) 普通全局变量的作用域为全局(整个软件,可跨域文件,其他文件想使用可以使用extern声明),函数中的静态变量的作用域为该函数。
3) 静态全局变量,的作用域则被限制在该文件中,所以,这个时候其他文件通过extern想使用该文件是不行的,(就算成功啦,那是因为你引用了其他文件中的定义)。同时,由于作用域被限制在当前文件,所以,不同的文件定义自己的全局变量就不会担心与其他文件出现冲突。
所以,这里就有一个有关全局变量定义的标准了。
1) 如果你在这个文件中定义的全局变量不打算给别人用,那么你就将它定义为static全局变量吧!因为这样你不必担心其他文件也定义了一个同名变量,在连接的时候出现重定义。
2) 如果你的全局变量是打算给其他文件使用的,那么就不要加上static,因为这样在其他文件中可以使用extern对该定义进行引用。
3) 这么说来,static 和extern是不能同时用来修饰一个变量的,extern修饰表示该变量只是声明,声明它使用了其他文件的变量定义,static的修饰表示我这个变量(自己定义的),只能被当前文件访问。两者完全冲突,所以编译器会报错——‘n’的声明中有相互冲突的限定符。
Extern有两种用法:
(1)      与C一起使用 extern C ,来在C++中表达,在编译的时候按照C的风格进行编译。
(2)      于是普通修饰全局变量的声明,(extern  int n;)注意它只能是声明,不能定义初始化,它声明表示,该变量可以从另外一个文件中找到,现在大胆使用就行了。到时候(链接的时候)就可以找到了,所以我认为这个extern关键是来支持,当前文件可以通过编译器的检查。当前文件使用了另外一个文件内定义的东西,但是有不能直接#include它,所以这导致这种技术的出现。注意,必须有一个文件定义了该变量(int n;)如果没有一个文件定义了它,那么编译的时候能够通过,但是在连接的时候,文件找不到你给它的承诺,所以就会报错——undefined reference to `n'。
Static的应用场景:
(1)      在C++面向对象中修饰成员函数或变量,这表明它所属范围为这个类,而不是对象。
(2)      在局部变量中(函数中)修饰变量,表示该变量是这个函数范围内的不变的,而不是随着每一次的函数呗调用而更新。所以你会发现,static修饰函数中的变量和修饰类中的成员有异曲同工之妙。函数每次被调用,类似于类每次被实例化。普通的成员都会是一个新的,而static成员与至始至终属于该函数(类)。
(3)      在全局变量中修饰变量,表示该变量的作用范围为当前文件,而不是整个程序。
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,