標籤:
本文目錄
- 一、在Java中,全域變數的定義沒有嚴格的位置規定
- 二、在C語言中,全域變數定義的位置是有限制的
- 三、重複定義同一個變數
- 四、不同源檔案中的同名變數
- 五、static關鍵字
- 六、static和extern的總結
說明:這個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;,它們代表的都是同一個變數。
第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;都代表著同一個變數。
注意: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關鍵字
但很多時候,我們並不想讓源檔案中的全域變數跟其他源檔案分享權限設定,相當於私人的全域變數,那麼你就得用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的作用在於限制該全域變數的範圍,只能在定義該全域變數的檔案中才能使用,跟其他源檔案中的同名變數互不干擾
【C語言】20-static和extern關鍵字2-對變數的作用