淺談C中靜態變數與全域性變數初始化時間
int a;
main()
{
while(1)
{
static b=1;
a=2;
b++;
a++;
}
}
我們所理解的靜態變數b,只知道它在上面的函式內部只初始化一次,其實是個假像 ,我要表達的是,事實上b初始化的值,不是在迴圈體完成的.繼續下看.
while(1)
{
static b=1;
a=2;
b++;
a++;
}
注意這一句:
static b=1;為什麼我們迴圈體無限迴圈,b 他只會賦一次值呢,從C上面是看不出來的.
經過我反彙編發現,
static b=1; 根本不在迴圈體中.可以想像,程式被譯成目標機器的時候是這個樣子
while(1)
{
//static b=1; 這句沒有!
a=2;
b++;
a++;
}
那麼b是什麼時候賦的值呢,是編譯的時候就確定了。。就是說,編譯的時候,就給b初始化好了!
類似,我們定義全域性變數,如果不賦值,編譯器給他賦上0.如果定義了值,就在編譯的時候就確定下來了,這個值是編譯器根據我們的語句賦給它的.而不程式中指令賦給它的!
那麼這個 a,b變數都在哪呢,他們呆在所謂的靜態儲存區(後面有介紹),物理上整個程式中任意程式碼都能訪問到這片區域,說明他們在儲存上是一樣的.但是a,b區別又在哪呢,就是對他們的引用,編譯器,允許你任何地方,函式中呼叫a,而b,不行,他有區域性作用域,比如你在一個函式中聲明瞭靜態變數b,那隻能在這函式中呼叫b.如果在其它的地方呼叫它,編譯器會報錯.這就是邏輯上的控制,而實際上,"物理"上是允許程式在任意地方訪問b變數,但是編譯器哥哥不會讓你訪問.
那什麼又叫靜態儲存區呢,我個人認為就是這是安全區域,不會隨便被別的變數替掉.分給你的就是你的,不會被別人給佔了.
談到這裡我們順便提一下,我們其它函式的區域性變數存在記憶體中的位置,區域性變數存放在棧中,棧是一片特殊記憶體區域,多個變數可能共享使用這片區域,這裡我們就可以看到一個問題,既然共享使用,假如我們宣告一個區域性變數,如果不賦初值,這個變數所在棧中的位置,這個位置包含的值,是隨機的,是上次別的變數留下來的值.