extern深度解析

2021-06-18 03:51:31 字數 2447 閱讀 2585

c語言中extern用法:

對於全域性變數來說,extern關鍵字可以在乙個模組中使用在另乙個模組中定義的全域性變數.只要extern宣告一下就好,但是變數只能定義一次,不然鏈結的時候會報錯.(現代

編譯器一般採用按檔案編譯的方式,因此在編譯時,各個檔案中定義的

全域性變數

是互相不透明的。也就是說,在編譯時,

全域性變數

的可見域限制在檔案內部。

但是到了鏈結階段,要將各個檔案的內容「合為一體」,因此,如果某些檔案中定義的

全域性變數

名相同的話,在這個時候就會出現錯誤,也就是上面提示的重複定義的錯誤。

因此,各個檔案中定義的

全域性變數

名不可相同。這個特性也是我們使用extern的前提。)

對於函式來講extern的用法和全域性變數是一樣的,但是,我們更習慣於在標頭檔案中宣告其他模組可能用到的全域性變數和函式,區別在於全域性變數前一般加extern,而函式則可加可不加.(值得注意的是標頭檔案可能包含在多個原始檔中,所以不應該有變數或者函式的定義,但是也有三個例外:標頭檔案可以定義類,值在編譯時就已經知道的const物件和inline函式)

附:const物件只存在於定義的那個檔案中,不能被其他檔案訪問,同樣可以指定const物件為extern,就可以在整個程式中訪問const物件.

c++中extern用法:

作為一種物件導向的語言,c++支援函式過載,而過程式語言c則不支援。函式被c++編譯後在符號庫中的名字與c語言的不同。例如,假設某個函式的原型為:void foo( int x, int y );該函式被c編譯器編譯後在符號庫中的名字為_foo,而c++編譯器則會產生像_foo_int_int之類的名字。

未加extern "c"宣告時的連線方式

假設在c++中,模組a的標頭檔案如下:

// 模組a標頭檔案 modulea.h

#ifndef module_a_h

#define module_a_h

int foo( int x, int y );

#endif

在模組b中引用該函式:

// 模組b實現檔案 moduleb.cpp

#i nclude "modulea.h"

foo(2,3);

實際上,在連線階段,聯結器會從模組a生成的目標檔案modulea.obj中尋找_foo_int_int這樣的符號。

加extern "c"宣告後的編譯和連線方式

加extern "c"宣告後,模組a的標頭檔案變為:

// 模組a標頭檔案 modulea.h

#ifndef module_a_h

#define module_a_h

extern "c" int foo( int x, int y );

#endif

在模組b的實現檔案中仍然呼叫foo( 2,3 ),其結果是:

(1)模組a編譯生成foo的目標**時,沒有對其名字進行特殊處理,採用了c語言的方式;

(2)聯結器在為模組b的目標**尋找foo(2,3)呼叫時,尋找的是未經修改的符號名_foo。

如果在模組a中函式宣告了foo為extern "c"型別,而模組b中包含的是extern int foo( int x, int y ) ,則模組b找不到模組a中的函式;反之亦然。

結論:extern "c"修飾的變數和函式是按照c語言方式編譯和連線的

extern "c"的慣用法

(1)在c++中引用c語言中的函式和變數,在包含c語言標頭檔案(假設為cexample.h)時,需進行下列處理:

extern "c"

而在c語言的標頭檔案中,對其外部函式只能指定為extern型別,c語言中不支援extern "c"宣告,在.c檔案中包含了extern "c"時會出現編譯語法錯誤。

(2)在c中引用c++語言中的函式和變數時,c++的標頭檔案需新增extern "c",但是在c語言中不能直接引用宣告了extern "c"的該標頭檔案,應該僅將c檔案中將c++中定義的extern "c"函式宣告為extern型別。

//c++標頭檔案 cppexample.h

#ifndef cpp_example_h

#define cpp_example_h

extern "c" int add( int x, int y );

#endif

//c++實現檔案 cppexample.cpp

#i nclude "cppexample.h"

int add( int x, int y )

/* c實現檔案 cfile.c

/* 這樣會編譯出錯:#i nclude "cexample.h" ,所以只能在.c檔案中使用extern來宣告*/

extern int add( int x, int y );

int main( int argc, char* argv )

特別說明:如果使用函式指標的方法,那麼c/c++之間的函式編譯後差異化可以無視,即可不使用extern 「c」。

extern關鍵字解析

程式的編譯單位是源程式檔案,乙個原始檔可以包含乙個或若干個函式。函式內定義的變數是區域性變數,而在函式之外定義的變數則稱為外部變數,外部變數也就是全域性變數。它的儲存方式為靜態儲存,其生存週期為整個程式的生存週期。全域性變數可以為本檔案中的其他函式所共用,它的有效範圍為從定義變數的位置開始到本原始檔...

8 extern 解析與用法

1 基本解釋 extern 可以置於變數或者 函式前,以標示變數或者 函式的定義在別的檔案中,提示編譯器遇到此變數和 函式時在其他模組中尋找其定義。另外,extern 也可用來進行鏈結指定。使用 extern 時候要嚴格對應宣告時的格式。extern 用在變數宣告中常常有這樣乙個作用,你在 c檔案中...

Const 深度解析

物件導向是c 的重要特性.但是c 在c的基礎上新增加的幾點優化也是很耀眼的 就const直接可以取代c中的 define 以下幾點很重要,學不好後果也也很嚴重 1.const常量,如const int max 100 優點 const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安...