【C語言】20-static和extern關鍵字2-對變量的作用


說明:這個C語言專題,是學習iOS開發的前奏。也為了讓有面向對象語言開發經驗的程序員,能夠快速上手C語言。如果你還沒有編程經驗,或者對C語言、iOS開發不感興趣,請忽略

上一講介紹了static和extern對函數的作用,static用來定義一個內部函數,不允許其他文件訪問;extern用來定義和聲明一個外部函數,允許其他文件訪問。static和extern對變量也有作用,不過跟函數有點差別。

 

C語言和Java都有全局變量的概念,但是它們的用法還是有些差別的。

一、在Java中,全局變量的定義沒有嚴格的位置規定

全局變量可以定義在類的最前面,也可以定義在類的最尾端,也就說一個方法可以訪問在它之后定義的變量。

可以看到,第4行定義的test方法可以訪問第8行定義的變量a,這是完全沒有問題的。

 

二、在C語言中,全局變量定義的位置是有限制的

默認情況下,一個函數不可以訪問在它后面定義的全局變量

在第4行定義的main函數中嘗試訪問第9行定義的變量a,編譯器直接報錯了。

解決這個錯誤的話,有2種辦法:

第1種辦法:將變量a定義在main函數的前面

這樣做編譯器就不會找你麻煩了。

 

第2種辦法:在main函數前面對變量a進行提前聲明

也就是讓main函數知道變量a的存在就行了,至於變量a定義在哪個位置,main函數不用管。

* 完整的變量聲明需要用extern關鍵字

第3行是對變量a進行聲明,第10行是定義變量a,再次強調,聲明和定義是兩碼事。在第6行操作的就是第10行定義的變量a。

注意:你不能省略第10行的定義,只留下第3行的聲明,因為extern是用來聲明一個已經定義過的變量。

 

三、重復定義同一個變量

* 其實,你也可以直接在main函數前面再定義一次a

看到這一幕,你可能很驚訝,但編譯器是不會報錯的。在這種情況下,第3行和第10行的變量a代表着同一個變量

 

* 以此類推,如果我們寫了無數遍全局變量int a;,它們代表的都是同一個變量(因為Xcode的編譯器自動在其他的int a前面都加了一個extern關鍵字,相當於是extern int a。只留一下一個int a用來定義變量a,其他都是在引用變量a)。

第3到第6行、第13到第17行的變量a都代表着同一個變量。

 

* 還要注意的一點是,我們也可以將全局變量a聲明為局部變量后再使用!!!

注意:第2、第5、第6、第10行都代表着同一個變量。其實,從第6行a的顏色(淺藍色)都可以看出,這個a依然是個全局變量。

(這是Xcode的特性,如果在函數內部訪問了全局變量,全局變量就會顯示淺藍色,如果函數內部訪問的是局部變量,局部變量就顯示普通的黑色。當然,不同的開發工具有不同的顯示方案)

 

* 但是,如果你將第5行的extern去掉,那情況就完全不一樣了,相信有編程經驗的你都懂得這是什么情況了

第2、第10行代表着同一個全局變量,而第5、第6行則是一個局部變量,跟外面的那個全局變量沒有半毛錢的關系。其實從第5、6行a的顏色(黑色)都可以看出是個局部變量。

 

四、不同源文件中的同名變量

前面講到,你在一個源文件中無論寫多少遍全局變量int a;,它們代表的都是同一個變量。還有一個事實,假如在另一個源文件中也有全局變量int a;,那么這兩個源文件的所有全局變量int a;都代表着同一個變量。extern關鍵字還是適用的,比如:


或者是:

上面的兩種情況下,test.c和main.c中使用的全局變量a都還是代表着同一個變量

注意了,不可以兩個文件的所有全部變量a都用extern,下面的做法是錯誤的:

因為extern是用來聲明一個已經定義過的變量,這兩個文件都是在聲明變量,沒有人定義變量,在鏈接的時候肯定報錯:

大致錯誤意思是:標示符a未定義

 

五、static關鍵字

但很多時候,我們並不想讓源文件中的全局變量跟其他源文件共享,相當於私有的全局變量,那么你就得用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是分別代表着不同變量

 

六、static和extern的總結

1.extern可以用來聲明一個全局變量,但是不能用來定義變量

2.默認情況下,一個全局變量是可以供多個源文件共享的,也就說,多個源文件中同名的全局變量都代表着同一個變量

3.如果在定義全局變量的時候加上static關鍵字,此時static的作用在於限制該全局變量的作用域,只能在定義該全局變量的文件中才能使用,跟其他源文件中的同名變量互不干擾


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM