搞不定的C語言 extern的作用

2021-09-13 00:11:25 字數 3153 閱讀 3143

在c語言中,修飾符extern用在變數或者函式的宣告前,用來說明「此變數/函式是在別處定義的,要在此處引用」。

1. extern修飾變數的宣告。舉例來說,如果檔案a.c需要引用b.c中變數int v,就可以在a.c中宣告extern int v,然後就可以引用變數v。這裡需要注意的是,被引用的變數v的鏈結屬性必須是外鏈結(external)的,也就是說a.c要引用到v,不只是取決於在a.c中宣告extern int v,還取決於變數v本身是能夠被引用到的。這涉及到c語言的另外乙個話題--變數的作用域。能夠被其他模組以extern修飾符引用到的變數通常是全域性變數。還有很重要的一點是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函式fun定義的開頭處宣告extern int v,然後就可以引用到變數v了,只不過這樣只能在函式fun作用域中引用v罷了,這還是變數作用域的問題。對於這一點來說,很多人使用的時候都心存顧慮。好像extern宣告只能用於檔案作用域似的。

2. extern修飾函式宣告。從本質上來講,變數和函式沒有區別。函式名是指向函式二進位制塊開頭處的指標。如果檔案a.c需要引用b.c中的函式,比如在b.c中原型是int fun(int mu),那麼就可以在a.c中宣告extern int fun(int mu),然後就能使用fun來做任何事情。就像變數的宣告一樣,extern int fun(int mu)可以放在a.c中任何地方,而不一定非要放在a.c的檔案作用域的範圍中。對其他模組中函式的引用,最常用的方法是包含這些函式宣告的標頭檔案。使用extern和包含標頭檔案來引用函式有什麼區別呢?extern的引用方式比包含標頭檔案要簡潔得多!extern的使用方法是直接了當的,想引用哪個函式就用extern宣告哪個函式。這大概是kiss原則的一種體現吧!這樣做的乙個明顯的好處是,會加速程式的編譯(確切的說是預處理)的過程,節省時間。在大型c程式編譯過程中,這種差異是非常明顯的。

3. 此外,extern修飾符可用於指示c或者c++函式的呼叫規範。比如在c++中呼叫c庫函式,就需要在c++程式中用extern 「c」宣告要引用的函式。這是給鏈結器用的,告訴鏈結器在鏈結的時候用c函式規範來鏈結。主要原因是c++和c程式編譯完成後在目標**中命名規則不同。

用c語言編寫程式的時候,我們經常會遇到這樣一種情況:

希望在標頭檔案中定義乙個全域性變數,然後包含到兩個不同的c檔案中,希望這個全域性變數能在兩個檔案中共用

舉例說明:

專案資料夾project下有main.c、common.c和common.h三個檔案,其中common.**件分別#include在main.c和common.c檔案中。現在希望宣告乙個字元型變數key,在main.c和common.c中公用。如下圖所示:

有人想,既然是想兩個檔案都用,那就在common.h中宣告乙個unsigned char key,然後由於包含關係,在main.c和common.c中都是可見的,所以就能共用了。

這種想法其實是很多初學者都會想到的,想起來確實有道理,但是實際寫出來,我們發現編譯的時候編譯器提示出錯,一般提示大概都類似於:

error: l6200e: symbol key multiply defined (by common.o and main.o).

也就是說編譯器認為我們重複定義了key這個變數。這是因為#include命令就是原封不同的把頭檔案中的內容搬到#include的位置,所以相當於main.c和common.c中都執行了一次unsigned char key,而

c語言中全域性變數是專案內(或者叫工程內)可見的

,這樣就造成了乙個專案中兩個變數key,編譯器就認為是重複定義。

正確的解決辦法:使用

extern關鍵字來

宣告

變數為外部變數。具體說就是在其中乙個c檔案中

定義

乙個全域性變數

key,然後在另乙個要使用

key這個變數的c檔案中使用

extern關鍵字

宣告一次,說明這個變數為外部變數,是在其他的c檔案中定義的全域性變數。請注意我這裡的用詞:

定義

宣告。例如在main.c檔案中定義變數key,在common.c檔案中宣告key變數為外部變數,這樣這兩個檔案中就能共享這個變數

key了,如下圖所示。

**如下(只寫跟我們所說問題有關的部分):

(1)main.c檔案

#include 

"common.h

"unsigned char 

key;

(2)common.c檔案:

#include

"common.h

"externunsigned char 

key;

很多人看了可能糊塗,這裡稍微說一下,其實就是

變數定義

變數宣告的區別,

變數定義使用「資料型別+變數名稱」的形式

,編譯器需要給他分配記憶體單元的

;而變數宣告使用「extern 變數型別+變數名稱」的形式,是告訴編譯器我這個變數將在其他外部c檔案中定義,我這裡只是在外部用它

。編譯器就不給他分配記憶體空間,而等到真正遇到變數定義的時候再給他分配記憶體空間。

由於很多人從開始學c語言就一直把

定義變數

宣告變數,一開始就叫錯了,所以導致現在分不清

定義

宣告的區別。要是還理解不了就想想

函式的定義

宣告,函式定義是編寫函式功能實體,編譯器要編譯這個函式並且要分配記憶體空間,而函式宣告並不生成函式功能實體,只是告訴編譯器這是個函式,這個函式在後面將會定義實體,我這裡只是提前用,編譯器就會接著繼續往下編譯,如果子函式寫在main函式之後,那麼宣告是必須的,如果不宣告函式編譯器都不知道這是個函式,編譯就會報錯。

C語言中的extern

在c語言中,修飾符extern用在變數或者函式的宣告前,用來說明 此變數 函式是在別處定義的,要在此處引用 1.extern修飾變數的宣告。舉例來說,如果檔案a.c需要引用b.c中變數int v,就可以在a.c中宣告extern int v,然後就可以引用變數v。這裡需要注意的是,被引用的變數v的鏈...

C語言extern的用法

利用關鍵字extern,可以在乙個檔案中引用另乙個檔案中定義的變數或者函式,下面就結合具體的例項,分類說明一下。一 引用同乙個檔案中的變數 include int func int main int num 3 int func 如果按照這個順序,變數 num在main函式的後邊進行宣告和初始化的話...

C語言中的extern

extern可以置於變數或者函式前,以表示變數或者函式的定義在別的檔案中,提示編譯器遇到此變數和函式時在其他模組中尋找其定義。另外,extern也可用來進行鏈結指定。在乙個原始檔裡定義了乙個陣列 char a 6 在另外乙個檔案裡用下列語句進行了宣告 extern char a 請問,這樣可以嗎?答...