我們知道,c語言中沒有類的概念,**都是以檔案為單位組織的。對於非區域性變數和函式,只能在唯一的乙個c檔案中定義一次,多檔案同時定義就會導致編譯器報重複定義的錯誤。而為了能在其他c**檔案中使用這些非區域性變數和函式,就有了extern關鍵字。同時,為了檔案的**隔離,有些變數和函式不想被其他檔案訪問,就有了static關鍵字。
下面將圍繞extern和static說明它們的作用。
1.1 extern修飾變數
為了使用在其他檔案或其他地方定義的變數,需要使用extern來宣告該變數。這裡的"其他地方",比如在c++中,同乙個原始碼檔案,在定義該變數之前使用該變數;
當然在較老版本的c中,變數和函式必須先定義,才能使用。
舉例來說,在a.c中定義的 int a; ,在b.c中 extern int a;,如果放於某個函式中,則可見性僅限該函式內;如果放於函式外,則對於定義該函式的檔案內的所有函式都是可見的。
extern int a; 要求a的鏈結屬性是外鏈結(external)的,如果a本身不符合外鏈結屬性,即使extern修飾了該變數,也引用不成功。
1.2 extern修飾函式
與extern修飾變數類似,被修飾的函式也應是外鏈結的,才能引用。
1.3 extern和include
我們知道,引用其他模組的函式和變數,最常見的就是使用"#include"來修飾包含被引用函式的標頭檔案,和這裡extern作用類似。它們的區別主要是:
"include"宣告標頭檔案一次,就可以批量應用該標頭檔案下的所有外鏈結的函式和變數;extern只能一次宣告乙個變數或函式;
extern目標明確,直接了當,**結構清晰,也會加速編譯過程,節省時間;
所以,如果需要多次引用同乙個檔案下的函式或變數,用"include"合適;否則使用extern合適。
1.4 extern "c"
在c++中呼叫c庫,經常見到這樣的**,來宣告要使用的函式是來自c中的。作用是告訴鏈結器,要使用c的函式命名規範來鏈結,而不是c++的。
因為c++編譯後的函式命名和c的不同,如果使用c++的命名,鏈結器可能找不到編譯後的函式。
2.1 static區域性變數
區域性變數在函式中定義,通常是存放在棧中的,它的生命週期隨著函式執行的結束而終止。而static修飾區域性變數後,它存放於靜態儲存區.data段,.data段裡面存放已初始化的全域性變數。static區域性變數的生命週期將隨程式的結束而終止,而與定義它的函式的執行無關。但是由於它仍是乙個區域性變數,故它的作用域仍然是該函式內。同時,該變數只在初次定義時被初始化一次。如果沒有顯示的初始,那麼系統會預設賦值。對於int型變數,系統會自動對其賦值為0,對於字元陣列,會自動賦值為'\0'。
對於一次程式執行而言,static區域性變數的每次操作,都是在上一次操作後的值的基礎上進行操作的,對於多執行緒程式設計,這是需要注意的地方,需要做好**塊同步。
2.2 static全域性變數
前面我們提到,可以通過extern修飾變數來引用在其他地方定義的全域性變數,且該變數需為外鏈結的。而如果定義的全域性變數不想被其他檔案引用,即只在定義該全域性變數的檔案內有效的話,可以用static修飾全域性變數達到這樣的效果。這叫做靜態全域性變數。和其他的全域性變數的儲存相同,靜態全域性變數也是在.data段(已初始化)或者.bss段(未初始化)內存放的。
2.3 static函式
同static全域性變數一樣,static修飾函式也將函式的訪問範圍限定在了定義該函式的檔案內部。外界的extern引用訪問會報編譯錯誤。好比物件導向語言中類中的private修飾符一樣。
其實上面我們已經說的很清楚了,static修飾的變數和函式的作用範圍北限定於定義它們的檔案內部。而extern修飾的變數和函式說明要引用在其他地方定義的變數和函式,顯然這是兩個矛盾的修飾符。更深層次的講,extern要求引用的變數和函式是外鏈結的,他需要通過符號表名稱進行鏈結,而static恰恰會移除符號表名稱。即使在同乙個檔案裡,static和extern同時修飾乙個變數或函式來宣告,之後再用static定義該函式, 依然是編譯報錯的。有興趣的朋友可以去試試。
以上就是我對c中的static和extern總結,如有不足之處,歡迎指正。
C和C 中static的作用
在c語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條。1 先來介紹它的第一條也是最重要的一條 隱藏。當我們同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性。為理解這句話,我舉例來說明。我們要同時編譯兩個原始檔,乙個是a.c,另乙個是main.c。...
C和C 中static的作用
在c語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條。1 先來介紹它的第一條也是最重要的一條 隱藏。當我們同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性。為理解這句話,我舉例來說明。我們要同時編譯兩個原始檔,乙個是a.c,另乙個是main.c。...
C和C 中static變數
c語言中static的變數 1 static區域性變數 a 靜態區域性變數在函式內定義,生存期為整個程式執行期間,但作用域與自動變數相同,只能在定義該變數的函式內使用。退出該函式後,儘管該變數還繼續存在,但不能使用它。b 對基本型別的靜態區域性變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變...