extern的簡單使用

2021-08-21 12:20:13 字數 2771 閱讀 9510

extern用在變數宣告中常常有這樣乙個作用:你要在*.c檔案中引用另乙個檔案中的乙個全域性的變數,那就應該放在*.h中用extern來宣告這個全域性變數。        

這個關鍵字真的比較可惡,在定義(函式)的時候,這個extern居然可以被省略,所以會讓你搞不清楚到底是宣告還是定義,下面分變數和函式兩類來說:

尤其是對於變數來說。

extern int a;//宣告乙個全域性變數a

int a; //定義乙個全域性變數a

extern int a =0 ;//定義乙個全域性變數a 並給初值。一旦給予賦值,一定是定義,定義才會分配儲存空間。

int a =0;//定義乙個全域性變數a,並給初值,

宣告之後你不能直接使用這個變數,需要定義之後才能使用。

第四個等於第三個,都是定義乙個可以被外部使用的全域性變數,並給初值。

糊塗了吧,他們看上去可真像。但是定義只能出現在一處。也就是說,不管是int a;還是int a=0;都只能出現一次,而那個extern int a可以出現很多次

當你要引用乙個全域性變數的時候,你就要宣告extern int a;這時候extern不能省略,因為省略了,就變成int a;這是乙個定義,不是宣告。

現代編譯器一般採用按檔案編譯的方式,因此在編譯時,各個檔案中定義的全域性變數是互相不透明的。也就是說,在編譯時,全域性變數的可見域限制在檔案內部。

下面舉乙個簡單的例子:

建立乙個工程,裡面含有a.cpp和b.cpp兩個簡單的c++原始檔:

int i;

int main()

int i;

這兩個檔案極為簡單,在a.cpp中我們定義了乙個全域性變數i,在b中我們也定義了乙個全域性變數i。

linking...

b.obj:error lnk2005:"inti"(?i@@3ha)already defined in a.obj

debug/a.exe:fatal error lnk1169:one or more multiply defined symbols found

error executing link.exe.

a.exe-2 error(s),0 warning(s)

這就是說,在編譯階段,各個檔案中定義的全域性變數相互是不透明的,編譯a時覺察不到b中也定義了i,同樣,編譯b時覺察不到a中也定義了i。

但是到了鏈結階段,要將各個檔案的內容「合為一體」,因此,如果某些檔案中定義的全域性變數名相同的話,在這個時候就會出現錯誤,也就是上面提示的重複定義的錯誤。

因此,各個檔案中定義的全域性變數名不可相同。

在鏈結階段,各個檔案的內容(實際是編譯產生的obj檔案)是被合併到一起的,因而,定義於某檔案內的全域性變數,在鏈結完成後,它的可見範圍被擴大到了整個程式。

這樣一來,按道理說,乙個檔案中定義的全域性變數,可以在整個程式的任何地方被使用,舉例說,如果a檔案中定義了某全域性變數,那麼b檔案中應可以使用該變數。修改我們的程式,加以驗證:

int main()

i = 100;//試圖使用b中定義的全域性變數

int i;

編譯結果如下:

compiling...

a.cpp

c:\documents and settings\wangjian\桌面\try extern\a.cpp(5):error c2065:'i':undeclared identifier

error executing cl.exe.

a.obj-1 error(s),0 warning(s)

編譯錯誤。

其實出現這個錯誤是意料之中的,因為檔案中定義的全域性變數的可見性擴充套件到整個程式是在鏈結完成之後,而在編譯階段,他們的可見性仍侷限於各自的檔案。

編譯器的目光不夠長遠,編譯器沒有能夠意識到,某個變數符號雖然不是本檔案定義的,但是它可能是在其它的檔案中定義的。

雖然編譯器不夠有遠見,但是我們可以給它提示,幫助它來解決上面出現的問題。這就是extern的作用了。

extern的原理很簡單,就是告訴編譯器:「你現在編譯的檔案中,有乙個識別符號雖然沒有在本檔案中定義,但是它是在別的檔案中定義的全域性變數,你要放行!」

我們為上面的錯誤程式加上extern關鍵字:

extern int i;

int main()

i=100;//試圖使用b中定義的全域性變數

int i;

順利通過編譯,鏈結

extern函式1

常見extern放在函式的前面成為函式宣告的一部分,那麼,c語言的關鍵字extern在函式的宣告中起什麼作用?

答案與分析:

如果函式的宣告中帶有關鍵字extern,僅僅是暗示這個函式可能在別的原始檔裡定義,沒有其它作用。即下述兩個函式宣告沒有明顯的區別:

extern int f(); 和int f();

當然,這樣的用處還是有的,就是在程式中取代include 「*.h」來宣告函式,在一些複雜的專案中,我比較習慣在所有的函式宣告前新增extern修飾。

extern函式2

當函式提供方單方面修改函式原型時,如果使用方不知情繼續沿用原來的extern申明,這樣編譯時編譯器不會報錯。但是在執行過程中,因為少了或者多了輸入引數,往往會造成系統錯誤,這種情況應該如何解決?

答案與分析:

目前業界針對這種情況的處理沒有乙個很完美的方案,通常的做法是提供放在自己的***_pub.h中提供對外部介面的宣告,然後呼叫包涵該檔案的標頭檔案,從而省去extern這一步。以避免這種錯誤。

寶劍有雙鋒,對extern的應用,不同的場合應該選擇不同的做法。

extern外部方法使用C 簡單例子

外部方法使用c 簡單例子 1 增加引用using system.runtime.interopservices 2 宣告和實現的連線 dllimport kernel32 setlasterror true 3 宣告外部方法public static extern int getcurrentdir...

extern的使用例項

利用關鍵字extern,實現全域性變數的共享 extern 變數只能一次定義 宣告定義 多次宣告。宣告 extern int a int a 宣告 定義 extern int a 0 int a 0 一 兩個cpp檔案之間共享 test.cpp includeusing namespace std ...

VC中extern的使用

extern為外部連線符號 通常是在定義介面 全域性變數 的時候這樣使用的,這樣的乙個宣告寫在標頭檔案內,供其他檔案包含。這時候extern表示函式的實現部份不在檔案內部,在連線的時候統一由聯結器處理,編譯器通常會假定編譯時候找不到實現部份的函式為extern形式.當然,加了extern也可以在該檔...