c++primer的解釋是這樣的:
變數的定義(definition):用於為變數分配儲存空間,還可以為變數指定初始值。在乙個程式中,變數有且僅有乙個定義;
變數的宣告(declaration):用於向程式表明變數的型別和名字。定義也是宣告:當定義變數時我們宣告了它的型別和名字。可以通過使用extern關鍵字宣告變數名而不定義它。
以上解釋講得還是比較清楚的,有分配空間的叫定義,沒分配空間的叫宣告。好吧,你不知道什麼時候分配什麼時候沒分配。讓我們換一種說法。
「定義也是宣告」,這說明宣告包括定義。所以諸如int a;extern int a;之類的一定是宣告。那是不是定義還要接著往下看;
如果程式前面都沒有出現過a這個變數,這時你要使用a,你必須讓程式知道你要使用a這個變數了。這時候你寫入int a;以前沒有a這個變數的,現在程式為了記住它,就得為他分配空間,於是這是個定義。
如果程式包含的其他檔案裡已經出現過a了,這證明程式已經為a分配記憶體,這時你要使用a就方便很多了。你只需要告訴程式,這個a在其他地方定義過了,於是你寫入extern int a;
對於int a;來說,它既是定義又是宣告;對於extern int a;來說,它是宣告不是定義。一般為了敘述方便,把建立儲存空間的宣告稱定義,而不把建立儲存空間的宣告稱為宣告.
[引申閱讀]**下c++的宣告和定義問題,關於extern
c++primer第四版中,53頁的習題2.18中問到,extern std::string name;是屬於宣告還是定義?答案說的是宣告。不過我認為,string類中有預設建構函式,如果該語句在函式外,那麼則會自動獲得儲存空間,將name定義為空字串,不知各位有何高見?
問題補充:
感謝回答我的關於extern的問題,可是還是沒想通。正如一樓舉的例子extern std:tring name("zhang3li4");我認為extern std::string name;和那句是一樣的 .因為標準庫中的string是有預設建構函式的,若後面什麼都沒有的話,就初始為空字串
------
我剛才做了乙個實驗:
#include
std::string i;
#include
#include
extern std::string i;
int main ()
執行結果為:
(上面是一空行:由於末尾用了endl)
如果沒有a.cpp這個檔案,執行出錯
這是一對實驗(有沒有a.cpp檔案)
可得出這樣的結論:
a.cpp中std::string i;是定義(本來就是)
b.cpp中extern std::string i; 則是宣告(你的問題)
先別急,這只是實驗結果。我們還需要理論依據,那麼下面就試著解釋一下:
下面是另乙個例子(也是第二個實驗)
你應該知道內建型別(int等)如果作為全域性變數時,定義的同時也就初始化了(乙個內建型別有其對應的預設值;如果你將自定義型別也看成內建型別,那麼就等於說,乙個自定義型別有其對應的預設值(由預設建構函式完成))。如
int i;
#include
extern int i;
int main ()
那麼在這裡int i; 就是定義(並且初始化了i,初始值為0)
因而輸出結果為
0//這個實驗的執行結果符合理論依據。
(我使用的編譯器是visual studio 2008)
從這兩個實驗來看:(將兩個「預設」等同起來)
int i;
std::string i;
都可以作為初始化i的定義性語句。
那麼extern int i;
extern std::string i;
也具有定義行為(這個很明顯與extern的用法相悖)
在以上兩個試驗中:int 與 string 有「區別」嗎?所有的**都一樣只不過把std::string 換成了 int而已!如果你能解釋int的情況,那麼我想std::string問題也就迎刃而解了!
於是我個人總結出乙個結論:
不論是內建型別還是自定義型別,前面有extern關鍵字,如果沒有顯式地初始化引數(即就是自定義型別的預設建構函式被extern遮蔽了,不起初始化的作用),那麼就按宣告對待。
可能我的描述很混亂,希望你好好看看上面的例子,就明白了!
注意:從這裡可以看出來預設建構函式的特殊性!
摘自:
宣告和定義的區別
c primer 3rd 5.2宣告語句講得不清不楚的,還是effective c 2nd講得清楚 所謂宣告 declaration 就是用來將乙個object function class 或tempate的型別名稱告訴編譯器 宣告式並不帶有細節資訊 對object而言,其定義式是編譯器為它配置記...
宣告和定義的區別
宣告和定義的區別 2012 03 22 14 34 標籤 declare define 分類 c language 變數定義 用於為變數分配儲存空間,還可為變數指定初始值。程式中,變數有且僅有乙個定義。變數宣告 用於向程式表明變數的型別和名字。定義也是宣告 當定義變數時我們宣告了它的型別和名字。ex...
宣告和定義的區別
宣告和定義的區別 從編譯原理上來說 宣告是僅僅只告訴編譯器有某個型別變數被使用,編譯器並不會為它分配任何記憶體。而定義就是為其分配了記憶體空間。宣告不一定是定義,定義一定是定義 變數的定義 用於為變數分配儲存空間,也可為變數指定初始值,變數有且僅有乙個定義。變數的宣告 用於向程式表明變數的型別和名字...