在C語言里,全局變量如果不初始化的話,默認為0,也就是說在全局空間里:
int x =0; 跟 int x; 的效果看起來是一樣的。但其實這里面的差別很大,強烈建議大家所有的全局變量
都要初始化,他們的主要差別如下:
編譯器在編譯的時候針對這兩種情況會產生兩種符號放在目標文件的符號表中,對於初始化的,叫強
符號,未初始化的,叫弱符號。連接器在連接目標文件的時候,如果遇到兩個重名符號,會有以下處理規
則:
1、如果有多個重名的強符號,則報錯。
2、如果有一個強符號,多個弱符號,則以強符號為准。
3、如果沒有強符號,但有多個重名的弱符號,則任選一個弱符號。
大部分情況下,我們不希望連接器為我們做決定,所以我不是很認同后兩個規則,至少應該給個警告,
而不應該安靜地通過。因為這種問題引起的bug會很難查,所以我們要盡量把全局變量初始化,對於不想給
別的文件引用的變量,也盡量用static修飾。
除了連接時的表現不一樣外,未初始化的符號在目標文件的bss段中,而初始化的符號在data段中。
注: bss段(未手動初始化的數據)並不給該段的數據分配空間,只是記錄數據所需空間的大小。
data段(已手動初始化的數據)則為數據分配空間,數據保存在目標文件中。
對於局部變量,不被初始化的話,其值一般分為兩種情況Debug版和Release版的區別。
例:
#include "stdafx.h"
int i;
int main(int argc, char* argv[])
{
printf(" i = %d\n",i);
int j;
printf(" j= %d\n",j);
return 0;
}
在Debug版下,在這段代碼中i的值打印出來是0,而j的值打印出來是-858993460,也就是0xCCCCCCCC.
至於為什么是這個值,有網友給出這個解釋。(設計成0xcccccccc是有特殊用意的……這個好像叫做
Poison,未初始化的Pointer去取值的話會出錯。肯定有人問為什么不弄成0x00000000,因為空指針是指
針的有效狀態,可能會誤導人,而0xCCCCCCCC在Windows下永遠不可能是一個指針的有效狀態(不是NULL,
不指向一個對象,不指向一堆對象緊接之后的區域),這就是在模擬野指針……)
值得注意的是,同樣的代碼在Release版下,這段代碼中未被初始化的變量最后打印出來的可能都是0。
也有強大的網友給出解釋。(重點在於vc的一個功能:Catch release-build errors in debug build用
/GZ編譯開關打開。debug版這個開關是開的,release版是關的(為了效率)。這個開關說白了就是把所有
動態局部變量初始化成0xcccccccc,把所有動態堆變量初始化成0xcdcdcdcd。很多新手會忘記初始化這些
本來應該初始化的變量(尤其是new出來的變量),有時他們會假定這些變量應該是0,這樣就可能出現在
release版正常而debug版不正常的程序,因為release版至少局部變量的初始值很可能就是0,而有時他們
又會假定或者期望這些變量不是0,這樣就帶了一個最難發現的bug)
From:http://www.kingofcoders.com/viewNews.php?type=newsCpp&id=189&number=4836955386
-------------------------------------------------------------------------------------------------------------------------------------
不過個人去驗證局部變量,沒初始化,訪問會直接編譯不過。
相比類里的成員對象沒初始化變量的值也分對象構建的方式而不同:
struct Npc
{
int m;
int data;
};
Npc* pNpc = new Npc; // new Npc()
printf("m default value = %d\n", pNpc->m);
Npc()會調用默認構造函數,會對成員變量初始化0,new Npc則不會,data的值會是不確定的。