天天看點

extern

extern用法注意(轉)

用#include可以包含其他頭檔案中變量、函數的聲明,為什麼還要 extern關鍵字,如果我想引用一個全局變量或 函數a,我隻要直接在源檔案中包含#include<xxx.h> (xxx.h包含了a的聲明)不就可以了麼,為什麼還要用extern 呢??這個問題一直也是似是而非的困擾着我許多年了,今天上網狠狠查了一下總算小有 所獲了:

頭檔案

首先說下頭檔案,其實頭檔案對計算機而言沒什麼作用,她隻是在預編譯時在#include的地方展開一下,沒别的意義了,其實頭檔案主要是給别人看的。

我做過一個實驗,将頭檔案的字尾改成xxx.txt,然後在引用該頭檔案的地方用

#include"xxx.txt"

編譯,連結都很順利的過去了,由此可知,頭檔案僅僅為閱讀代碼作用,沒其他的作用了!

不管是C還是C++,你把你的函數,變量或者結構體,類啥的放在你的.c或者.cpp檔案裡。然後編譯成lib,dll,obj,.o等等,然後别人用的時候 最基本的gcc hisfile.cpp yourfile.o|obj|dll|lib 等等。

但對于我們程式員而言,他們怎麼知道你的lib,dll...裡面到底有什麼東西?要看你的頭檔案。你的頭檔案就是對使用者的說明。函數,參數,各種各樣的接口的說明。

    那既然是說明,那麼頭檔案裡面放的自然就是關于函數,變量,類的“聲明”了。記着,是“聲明”,不是“定義”。

那麼,我假設大家知道聲明和定義的差別。是以,最好不要傻嘻嘻的在頭檔案裡定義什麼東西。比如全局變量:

#ifndef _XX_頭檔案.H

#define _XX_頭檔案.H

int A;

#endif

那麼,很糟糕的是,這裡的int A是個全局變量的定義,是以如果這個頭檔案被多次引用的話,你的A會被重複定義

顯 然文法上錯了。隻不過有了這個#ifndef的條件編譯,是以能保證你的頭檔案隻被引用一次,不過也許還是會岔子,但若多個c檔案包含這個頭檔案時還是會 出錯的,因為宏名有效範圍僅限于本c源檔案,是以在這多個c檔案編譯時是不會出錯的,但在連結時就會報錯,說你多處定義了同一個變量,

Linking...

incl2.obj : error LNK2005: "int glb" (?glb@@3HA) already defined in incl1.obj

Debug/incl.exe : fatal error LNK1169: one or more multiply defined symbols found

注意!!!

extern

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

(1)變量

尤其是對于變量來說。

extern int a;//聲明一個全局變量a

int a; //定義一個全局變量a

extern int a =0 ;//定義一個全局變量a 并給初值。

int a =0;//定義一個全局變量a,并給初值,

第四個 等于 第 三個,都是定義一個可以被外部使用的全局變量,并給初值。

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

當你要引用一個全局變量的時候,你就要聲明,extern int a;這時候extern不能省略,因為省略了,就變成int a;這是一個定義,不是聲明。

(2)函數

     函數,函數,對于函數也一樣,也是定義和聲明,定義的時候用extern,說明這個函數是可以被外部引用的,聲明的時候用extern說明這是一個聲明。 但由于函數的定義和聲明是有差別的,定義函數要有函數體,聲明函數沒有函數體,是以函數定義和聲明時都可以将extern省略掉,反正其他檔案也是知道這個函數是在其他地方定義的,是以不加extern也行。兩者如此不同,是以省略了extern也不會有問題。

    比如:

int fun(void)

{

return 0;

}

很好,我們定義了一個全局函數

int fun(void);

我們對它做了個聲明,然後後面就可以用了

加不加extern都一樣

我們也可以把對fun的聲明 放在一個頭檔案裡,最後變成這樣

int fun(void);//函數聲明,是以省略了extern,完整些是extern int fun(void);

}//一個完整的全局函數定義,因為有函數體,extern同樣被省略了。

然後,一個客戶,一個要使用你的fun的客戶,把這個頭檔案包含進去,ok,一個全局的聲明。沒有問題。

但是,對應的,如果是這個客戶要使用全局變量,那麼要extern 某某變量;不然就成了定義了。

上一篇: extern
下一篇: extern

繼續閱讀