上一講介紹了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的做用在於限制該全局變量的做用域,只能在定義該全局變量的文件中才能使用,跟其餘源文件中的同名變量互不干擾