上一讲介绍了static和extern对函数的做用,static用来定义一个内部函数,不容许其余文件访问;extern用来定义和声明一个外部函数,容许其余文件访问。static和extern对变量也有做用,不过跟函数有点差异。html
C语言和Java都有全局变量的概念,可是它们的用法仍是有些差异的。ios
回到顶部编程
全局变量能够定义在类的最前面,也能够定义在类的最尾端,也就说一个方法能够访问在它以后定义的变量。函数
能够看到,第4行定义的test方法能够访问第8行定义的变量a,这是彻底没有问题的。工具
回到顶部开发工具
默认状况下,一个函数不能够访问在它后面定义的全局变量spa
在第4行定义的main函数中尝试访问第9行定义的变量a,编译器直接报错了。code
解决这个错误的话,有2种办法:orm
这样作编译器就不会找你麻烦了。htm
也就是让main函数知道变量a的存在就好了,至于变量a定义在哪一个位置,main函数不用管。
* 完整的变量声明须要用extern关键字
第3行是对变量a进行声明,第10行是定义变量a,再次强调,声明和定义是两码事。在第6行操做的就是第10行定义的变量a。
注意:你不能省略第10行的定义,只留下第3行的声明,由于extern是用来声明一个已经定义过的变量。
* 其实,你也能够直接在main函数前面再定义一次a
看到这一幕,你可能很惊讶,但编译器是不会报错的。在这种状况下,第3行和第10行的变量a表明着同一个变量。
* 以此类推,若是咱们写了无数遍全局变量int a;,它们表明的都是同一个变量。
第3到第6行、第13到第17行的变量a都表明着同一个变量。
* 还要注意的一点是,咱们也能够将全局变量a声明为局部变量后再使用!!!
注意:第二、第五、第六、第10行都表明着同一个变量。其实,从第6行a的颜色(浅蓝色)均可以看出,这个a依然是个全局变量。
(这是Xcode的特性,若是在函数内部访问了全局变量,全局变量就会显示浅蓝色,若是函数内部访问的是局部变量,局部变量就显示普通的黑色。固然,不一样的开发工具备不一样的显示方案)
* 可是,若是你将第5行的extern去掉,那状况就彻底不同了,相信有编程经验的你都懂得这是什么状况了
第二、第10行表明着同一个全局变量,而第五、第6行则是一个局部变量,跟外面的那个全局变量没有半毛钱的关系。其实从第五、6行a的颜色(黑色)均可以看出是个局部变量。
前面讲到,你在一个源文件中不管写多少遍全局变量int a;,它们表明的都是同一个变量。还有一个事实,假如在另外一个源文件中也有全局变量int a;,那么这两个源文件的全部全局变量int a;都表明着同一个变量。
注意:main.c和test.c中的全局变量a都表明着同一个变量。
咱们能够证实一下:
首先,在test.c中定义一个函数来查看a的值
而后在main.c的第9行修改a的值为10,而后调用test.c的test函数看看test.c中a的值
控制台的输出已经证实了一切。
* 固然,extern关键字仍是适用的,好比:
和
或者是:
和
上面的两种状况下,test.c和main.c中使用的全局变量a都仍是表明着同一个变量
注意了,不能够两个文件的全部所有变量a都用extern,下面的作法是错误的:
和
由于extern是用来声明一个已经定义过的变量,这两个文件都是在声明变量,没有人定义变量,在连接的时候确定报错:
大体错误意思是:标示符a未定义
但不少时候,咱们并不想让源文件中的全局变量跟其余源文件共享,至关于私有的全局变量,那么你就得用static关键字来定义变量。
这样写完,test.c和main.c的变量a分别表明着不一样的变量,它们是没有联系的、互不干扰的。也就是说,main.c没法访问test.c中的变量a,所以在main.c中将a修改成10后,test.c中的a依然为0。输出结果:。
其实static还能够用来修饰局部变量,这个在《变量类型》中说过,再也不阐述了。
* 由于main.c已经没有权限访问test.c中的变量a了,因此下面的写法是错误的:
和
extern是用来声明已经定义过并且可以访问的变量,虽然test.c中有定义过变量a,可是test.c中变量a的做用域是只限于test.c文件,main.c没有访问权限,因此main.c中的extern是废的。
连接的时候报错:标示符a未定义
除非main.c本身定义一个变量a,这样子extern才是有效的,不过这时候main.c和test.c中的变量a是分别表明着不一样变量
1.extern能够用来声明一个全局变量,可是不能用来定义变量
2.默认状况下,一个全局变量是能够供多个源文件共享的,也就说,多个源文件中同名的全局变量都表明着同一个变量
3.若是在定义全局变量的时候加上static关键字,此时static的做用在于限制该全局变量的做用域,只能在定义该全局变量的文件中才能使用,跟其余源文件中的同名变量互不干扰