以下內容由在論壇中討論而成,在此總結一下:
首先問題來自這個函數:
[cpp]
int fun()
{
static int i=0;
i++;
return i;
}
當這個函數被反復調用時,i的值是會一直加的,也就是靜態變量只被初始化了一次.
我對此產生了疑惑.不知道大家有沒有.
當改為:
[cpp]
int fun()
{
int i=0;
i++;
return i;
}
反復調用時都返回的是1; 這個例子很明白,雖然i這個變量時同名的,但是地址是不一樣的,這是一個新的變量,因為在作用域後,原變量被銷毀了.接著創建一個新的變量.
那麼這裡我們就知道了一件事情:就是靜態變量是全局的,和程序的生命周期是一樣的.
那麼原來的staic的i依然存在. 但是它的可訪問區域就只能是定義的作用域,而不一定能全局訪問,這是全局變量的一個差別.
而靜態變量的必須初始化,如果沒有顯示初始化,則初始化為0 ,'0'或者其他.
初始化在程序第一次加載中開始.並設置了相應的標志位!
所以當變量重復時,編譯器忽略了重復初始化的代碼,到這裡就算是C++只能初始化一次的原因了!
另外參考:
操作系統在加載程序時會根據程序中的聲明部分為程序分配內存空間(這部分數據是由編譯器生成的)。程序所支配的內存空間分為兩大部分:靜態區域和動態區域(至於為什麼這樣區分涉及到硬件知識,建議LZ不要深究):動態區域用於存儲經常會變動的數據(動態區域又分為兩大部分:棧和堆,關於這兩個部分大家應該都很熟悉了);靜態區域(Java裡稱為永久區域)用於存儲不會經常變化的數據,例如程序的指令代碼(C/C++裡就是各個函數編譯後得到的代碼)、用戶類型(結構體、類)的聲明代碼、全局變量、靜態變量……PS:有些例子提到用靜態變量來做遞歸的計數器,那只是為了說明靜態變量的特性。實際上不推薦這種用法,因為這樣會對程序性能造成輕微的影響。靜態區域內的數據會在程序加載時進行初始化,生存期為程序運行的全部時間。另外,糾正LZ的一個誤解:任何變量都只進行一次初始化。局部變量在程序塊結束時生存期就結束了,下次再調用這個程序塊時從原理上說聲明的是另一個變量了(分配到的地址也不一定一樣)。PS:在不同編譯器的不同編譯情況時,實際的內存分區可能不同。例如TC的Small模式下堆和棧區是重合的,而Tiny模式下連靜態區域和動態區域都是重合的。