每日一問3 C 中extern關鍵字的作用

2022-09-23 06:47:10 字數 2813 閱讀 7248

extern是c++引入的一個關鍵字,它可以應用於一個全域性變數,函式或模板宣告,說明該符號具有外部連結(external linkage)

屬性。也就是說,這個符號在別處定義。一般而言,c++全域性變數的作用範圍僅限於當前的檔案,但同時c++也支援分離式編譯,允許將程式分割為若干個檔案被獨立編譯。於是就需要在檔案間共享資料,這裡extern就發揮了作用。

符號的定義和宣告

在介紹extern之前,我們需要了解一下變數的宣告和定義。變數的宣告指向程式表名變數的型別和名字,即使得名字為程式所知,一個檔案如果想使用別處定義的名字則必須包含對那個名字的宣告。而變數的定義指申請儲存空間,並將其與變數名相關聯,除此之外,還可以為變數指定初始值。在程式中變數可以宣告多次,但只能定義一次。一般而言,定義就是宣告。但c++中由於extern的緣故,變數的宣告和定義是可以分開的。凡是沒有帶extern的宣告同時也都是定義。而對函式而言,帶有{}是定義,否則是宣告。如果想宣告一個變數而非定義它,就在變數名前新增關鍵字extern,且不要顯式的初始化變數。看下面的例子:

//

filea.cpp

int i; //

宣告並定義i

int j = 1; //

宣告並定義j

double max(double d1,double d2){} //

定義//

fileb.cpp

extern

int i; //

宣告i而非定義

extern

int j = 2; //

定義j而非宣告,會報錯,多重定義

int j; //

錯誤,重定義,注意這裡的j是在全域性範圍內宣告

extern

double max(double d1,double d2); //

宣告

c++中的連結屬性

連結屬性一定程度範圍決定著符號的作用域,c++中連結屬性有三種:none(無)、external(外部)和 internal(內部)

。extern有3種用法,分別如下:

最常見的用法,當連結器在一個全域性變數宣告前看到extern關鍵字,它會嘗試在其他檔案中尋找這個變數的定義。這裡強調全域性且非常量的原因是,全域性非常量的變數預設是外部連結的。

//

filea.cpp

int i = 1; //

宣告並定義全域性變數i

extern

int i; //

宣告i,連結全域性變數

extern

int i = 2; //

錯誤,多重定義

int i; //

錯誤,這是一個定義,導致多重定義

main()

//

filea.cpp

extern

const

int i = 1; //

定義//

fileb.cpp

//宣告

extern

const

int i;

在c++中,當與字串連用時,extern指明當前宣告使用了其他語言的連結規範,如extern "c",就指明使用c語言的連結規範。原因是,c++語言在編譯的時候為了解決函式的多型問題,會將函式名和引數聯合起來生成一箇中間的函式名稱,而c語言則不會,因此會造成連結時無法找到對應函式的情況,此時c函式就需要用extern “c”進行連結指定,這告訴編譯器,請保持我的名稱,不要給我生成用於連結的中間函式名。c和c++對函式的處理方式是不同的.extern "c"是使c++能夠呼叫c寫作的庫檔案的一個手段,如果要對編譯器提示使用c的方式來處理函式的話,那麼就要使用extern "c"來說明。

例子如下:

//

宣告printf函式使用c連結

extern"c

"int printf(const

char *fmt, ...);

//宣告指定的標頭檔案內所有的東西都使用 c 連結

extern"c

"//宣告函式showchar和getchar使用 c 連結

extern"c

"//定義函式 showchar 和 getchar 使用 c 連結

extern"c

"char showchar(char

ch)

extern"c

"char getchar(void

) //

宣告全域性變數 errno 為c連結

extern"c

"int

errno;

//又比如,在程式中常見的**段

#ifdef __cplusplus

extern"c

" #endif

//這裡__cplusplus是cpp中的自定義巨集,定義了這個巨集就表明這是一段cpp的**,也就是說,

//上面的**的含義是:如果這是一段cpp的**,那麼加入extern "c"處理其中的**。

與include相比,extern引用另一個檔案的範圍小,include可以引用另一個檔案的全部內容。extern的引用方式比包含標頭檔案要更簡潔。extern的使用方法是直接了當的,想引用哪個函式就用extern宣告哪個函式。這樣做的一個明顯的好處是,會加速程式的編譯(確切的說是預處理)的過程,節省時間。在大型c程式編譯過程中,這種差異是非常明顯的。

1.1.