【C语言】20-static和extern关键字2-对变量的作用
說明:這個(gè)C語言專題,是學(xué)習(xí)iOS開發(fā)的前奏。也為了讓有面向?qū)ο笳Z言開發(fā)經(jīng)驗(yàn)的程序員,能夠快速上手C語言。如果你還沒有編程經(jīng)驗(yàn),或者對(duì)C語言、iOS開發(fā)不感興趣,請(qǐng)忽略
上一講介紹了static和extern對(duì)函數(shù)的作用,static用來定義一個(gè)內(nèi)部函數(shù),不允許其他文件訪問;extern用來定義和聲明一個(gè)外部函數(shù),允許其他文件訪問。static和extern對(duì)變量也有作用,不過跟函數(shù)有點(diǎn)差別。
?
C語言和Java都有全局變量的概念,但是它們的用法還是有些差別的。
一、在Java中,全局變量的定義沒有嚴(yán)格的位置規(guī)定
全局變量可以定義在類的最前面,也可以定義在類的最尾端,也就說一個(gè)方法可以訪問在它之后定義的變量。
可以看到,第4行定義的test方法可以訪問第8行定義的變量a,這是完全沒有問題的。
?
二、在C語言中,全局變量定義的位置是有限制的
默認(rèn)情況下,一個(gè)函數(shù)不可以訪問在它后面定義的全局變量
在第4行定義的main函數(shù)中嘗試訪問第9行定義的變量a,編譯器直接報(bào)錯(cuò)了。
解決這個(gè)錯(cuò)誤的話,有2種辦法:
第1種辦法:將變量a定義在main函數(shù)的前面
這樣做編譯器就不會(huì)找你麻煩了。
?
第2種辦法:在main函數(shù)前面對(duì)變量a進(jìn)行提前聲明
也就是讓main函數(shù)知道變量a的存在就行了,至于變量a定義在哪個(gè)位置,main函數(shù)不用管。
* 完整的變量聲明需要用extern關(guān)鍵字
第3行是對(duì)變量a進(jìn)行聲明,第10行是定義變量a,再次強(qiáng)調(diào),聲明和定義是兩碼事。在第6行操作的就是第10行定義的變量a。
注意:你不能省略第10行的定義,只留下第3行的聲明,因?yàn)閑xtern是用來聲明一個(gè)已經(jīng)定義過的變量。
?
三、重復(fù)定義同一個(gè)變量
* 其實(shí),你也可以直接在main函數(shù)前面再定義一次a
看到這一幕,你可能很驚訝,但編譯器是不會(huì)報(bào)錯(cuò)的。在這種情況下,第3行和第10行的變量a代表著同一個(gè)變量。
?
* 以此類推,如果我們寫了無數(shù)遍全局變量int a;,它們代表的都是同一個(gè)變量(因?yàn)閄code的編譯器自動(dòng)在其他的int a前面都加了一個(gè)extern關(guān)鍵字,相當(dāng)于是extern int a。只留一下一個(gè)int a用來定義變量a,其他都是在引用變量a)。
第3到第6行、第13到第17行的變量a都代表著同一個(gè)變量。
?
* 還要注意的一點(diǎn)是,我們也可以將全局變量a聲明為局部變量后再使用!!!
注意:第2、第5、第6、第10行都代表著同一個(gè)變量。其實(shí),從第6行a的顏色(淺藍(lán)色)都可以看出,這個(gè)a依然是個(gè)全局變量。
(這是Xcode的特性,如果在函數(shù)內(nèi)部訪問了全局變量,全局變量就會(huì)顯示淺藍(lán)色,如果函數(shù)內(nèi)部訪問的是局部變量,局部變量就顯示普通的黑色。當(dāng)然,不同的開發(fā)工具有不同的顯示方案)
?
* 但是,如果你將第5行的extern去掉,那情況就完全不一樣了,相信有編程經(jīng)驗(yàn)的你都懂得這是什么情況了
第2、第10行代表著同一個(gè)全局變量,而第5、第6行則是一個(gè)局部變量,跟外面的那個(gè)全局變量沒有半毛錢的關(guān)系。其實(shí)從第5、6行a的顏色(黑色)都可以看出是個(gè)局部變量。
?
四、不同源文件中的同名變量
前面講到,你在一個(gè)源文件中無論寫多少遍全局變量int a;,它們代表的都是同一個(gè)變量。還有一個(gè)事實(shí),假如在另一個(gè)源文件中也有全局變量int a;,那么這兩個(gè)源文件的所有全局變量int a;都代表著同一個(gè)變量。extern關(guān)鍵字還是適用的,比如:
和
或者是:
和
上面的兩種情況下,test.c和main.c中使用的全局變量a都還是代表著同一個(gè)變量
注意了,不可以兩個(gè)文件的所有全部變量a都用extern,下面的做法是錯(cuò)誤的:
和
因?yàn)?span style="color:#ff6600;font-family:'courier new', courier;">extern是用來聲明一個(gè)已經(jīng)定義過的變量,這兩個(gè)文件都是在聲明變量,沒有人定義變量,在鏈接的時(shí)候肯定報(bào)錯(cuò):
大致錯(cuò)誤意思是:標(biāo)示符a未定義
?
五、static關(guān)鍵字
但很多時(shí)候,我們并不想讓源文件中的全局變量跟其他源文件共享,相當(dāng)于私有的全局變量,那么你就得用static關(guān)鍵字來定義變量。
這樣寫完,test.c和main.c的變量a分別代表著不同的變量,它們是沒有聯(lián)系的、互不干擾的。也就是說,main.c無法訪問test.c中的變量a,因此在main.c中將a修改為10后,test.c中的a依然為0。輸出結(jié)果:。
?其實(shí)static還可以用來修飾局部變量,這個(gè)在《變量類型》中說過,不再闡述了。
?
* 因?yàn)閙ain.c已經(jīng)沒有權(quán)限訪問test.c中的變量a了,所以下面的寫法是錯(cuò)誤的:
?和
extern是用來聲明已經(jīng)定義過而且能夠訪問的變量,雖然test.c中有定義過變量a,但是test.c中變量a的作用域是只限于test.c文件,main.c沒有訪問權(quán)限,所以main.c中的extern是廢的。
鏈接的時(shí)候報(bào)錯(cuò):標(biāo)示符a未定義
除非main.c自己定義一個(gè)變量a,這樣子extern才是有效的,不過這時(shí)候main.c和test.c中的變量a是分別代表著不同變量
?
六、static和extern的總結(jié)
1.extern可以用來聲明一個(gè)全局變量,但是不能用來定義變量
2.默認(rèn)情況下,一個(gè)全局變量是可以供多個(gè)源文件共享的,也就說,多個(gè)源文件中同名的全局變量都代表著同一個(gè)變量
3.如果在定義全局變量的時(shí)候加上static關(guān)鍵字,此時(shí)static的作用在于限制該全局變量的作用域,只能在定義該全局變量的文件中才能使用,跟其他源文件中的同名變量互不干擾
總結(jié)
以上是生活随笔為你收集整理的【C语言】20-static和extern关键字2-对变量的作用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: puppet最新源码包安装学习笔记
- 下一篇: Linux Cache 机制探究