
自動變量和靜態(tài)變量的初始化存在一個重要的差別。在靜態(tài)變量的初始化中,我們可以把可執(zhí)行程序文件想要初始化的值放在當程序執(zhí)行時變量將會使用的位置。當可執(zhí)行文件載入到內(nèi)存時,這個已經(jīng)保存了正確初始值的位置將賦值給哪個變量。完成這個任務并不需要額外的時間,也不需要額外的只了能夠,變量將會得到正確的值。如果不顯式地制定其初始值,靜態(tài)變量將初始化為0。自動變量的初始化需要更多的開銷,因為當程序鏈接時還無法判斷自動變量的存儲位置。事實上,函數(shù)的局部變量在函數(shù)的每次調(diào)用中可能占據(jù)不同的位置?;谶@個理由,自動變量沒有缺省的初始值,而顯式的初始化將在代碼塊的起始處插入一條隱士的賦值語句。
靜態(tài)變量:其初始化值被放在程序執(zhí)行時將使用的位置,所以不需額外時間,也不需額外指令。如果不顯示初始化,靜態(tài)變量將被初始化為0。
自動變量:程序鏈接時仍無法判斷變量的存儲位置。所以,自動變量沒有缺省的初始值,而顯示初始化將在代碼的起始處插入一條隱式賦值語句。
這導致了四種結(jié)果:
- 自動變量初始化較之賦值語句效率并無提高。除了聲明為const的變量之外,在聲明變量的同時進行初始化和先聲明后賦值只有風格只差,并無效率之別。
- 自動變量所在塊每次執(zhí)行時,都要對自動變量重新賦值。----這與靜態(tài)變量大不相同,后者只是在程序開始執(zhí)行前初始化一次。
- 由于初始化在運行時執(zhí)行,因此可以使用任何表達式作為初始化值。(這也解釋了為什么靜態(tài)變量的初始化不能使用表式)
- 除非對自動變量顯式初始化,否則當自動變量創(chuàng)建時,它的值一定是垃圾。
看下面的例題:
原文:http://blog.csdn.net/hanchaoman/article/details/8115073int a;
main()
{
while(1)
{
static b=1;
a=2;
b++;
a++;
}
}
我們所理解的靜態(tài)變量b,只知道它在上面的函數(shù)內(nèi)部只初始化一次,其實是個假像,我要表達的是,事實上b初始化的值,不是在循環(huán)體完成的.繼續(xù)下看.
while(1)
{
static b=1;
a=2;
b++;
a++;
}
注意這一句:
static b=1;為什么我們循環(huán)體無限循環(huán),b他只會賦一次值呢,從C上面是看不出來的.
經(jīng)過我反匯編發(fā)現(xiàn),
static b=1;根本不在循環(huán)體中.可以想像,程序被譯成目標機器的時候是這個樣子
while(1)
{
//static b=1; 這句沒有!
a=2;
b++;
a++;
}
那么b是什么時候賦的值呢,是編譯的時候就確定了。。就是說,編譯的時候,就給b初始化好了!
類似,我們定義全局變量,如果不賦值,編譯器給他賦上0.如果定義了值,就在編譯的時候就確定下來了,這個值是編譯器根據(jù)我們的語句賦給它的.而不程序中指令賦給它的!
那么這個a,b變量都在哪呢,他們呆在所謂的靜態(tài)存儲區(qū)(后面有介紹),物理上整個程序中任意代碼都能訪問到這片區(qū)域,說明他們在存儲上是一樣的.但是a,b區(qū)別又在哪呢,就是對他們的引用,編譯器,允許你任何地方,函數(shù)中調(diào)用a,而b,不行,他有局部作用域,比如你在一個函數(shù)中聲明了靜態(tài)變量b,那只能在這函數(shù)中調(diào)用b.如果在其它的地方調(diào)用它,編譯器會報錯.這就是邏輯上的控制,而實際上,"物理"上是允許程序在任意地方訪問b變量,但是編譯器哥哥不會讓你訪問.
那什么又叫靜態(tài)存儲區(qū)呢,我個人認為就是這是安全區(qū)域,不會隨便被別的變量替掉.分給你的就是你的,不會被別人給占了.
談到這里我們順便提一下,我們其它函數(shù)的局部變量存在內(nèi)存中的位置,局部變量存放在棧中,棧是一片特殊內(nèi)存區(qū)域,多個變量可能共享使用這片區(qū)域,這里我們就可以看到一個問題,既然共享使用,假如我們聲明一個局部變量,如果不賦初值,這個變量所在棧中的位置,這個位置包含的值,是隨機的,是上次別的變量留下來的值.
愛華網(wǎng)



