變數生命週期

在C語言中看到最多的東西就是「變數」了,因為對於變數的觀念就變的很重要了,需要了解變數如何宣告,變數的範疇和儲存週期以及關鍵字static,這邊來先來談談C語言中,變數範疇和儲存週期有那些要注意的地方。

※ 一個變數的生命是由

1. 儲存期而定 (storage duration)
2. 範疇 (scope)

※ 其中儲存期可分成

1. 自動存在期 (automatic duration)
2. 靜態存在期 (static duration)
3. 動態存在期 (dynamic duration)

而所謂的範疇則是變數中有效的範圍部份,在block內的變數不可被外部參考,在未看到宣告前不能被用到。

1. 自動存在期 (自動變數)

自動變數是在程式執行時在區塊開始時候才產生出來,當區塊結束後,變數就被「收回去了」,等下次又執行到此區段才會又建立此變數。

* 一般是我們放在main() function()幫忙運算,或是for(int i = 0)所用到的變數。
* 有效範圍是從被宣告開始,到區塊的結束。
* 一開始不設定值的話,內容值會是堆疊中沒有用的資料,為一無用的值。
* 每次區塊重新執行會重新建立此變數,若有初值,每次建立會重新指定初值。
* 此資料存在堆疊之中,非資料段,故使用完,超過block會將裡面的資料清除。

2. 靜態儲存在期 (全域變數、靜態自動變數、字串常數)

全域變數、靜態自動變數、字串常數屬於靜態變數,意思是當程式在linking time時已配置空間了,故這此變數是存在資料區段,而這此變數會和程式同生共死,程式開始執行前已存在了。

a.全域變數 (global variable)

* 宣告在所有的function外面,當宣告後其scope是後面的函式都可使用。
* 變數和程式共存亡。
* 若沒對此變數初值的話,會自動初值為0。

b.靜態自動變數 (static automatic variable)

* 宣告為static的自動變數,會和程式共存亡。
* 只俱有區塊的scope。
* 同時俱有全域變數般的生命週期,又俱有區塊般的可見性。
* 若沒對此變數初值的話,會自動初值為0。
* 當希望某函式內的某個變數,下次呼叫時仍然保持它上次呼叫的值的時候,使用static來宣告成靜態自動變數。

c.字串常數 (array of n const char)

* 是一種特例,在程式執行前已建立此空間,所以不論在程式中以指標指向那個字串常數,都可取,但不可存,因為是const且在記憶體中是連續的記憶體空間。
* 類似靜態自動變數,但是只要有指標指向,就可以取得內容。
* 字串常數和程式共存亡。
* 不可以反參照修改字串,因為是const。
* char str1[] = "this is string"; 自動存在期,反參照可修改字串內容。
* const char* str2 = "this is string"; 靜態存在期,反參照不可修改字串內容。

3. 動態存在期 (以malloc所配置出來的空間)

又稱為動態記憶體配置,使用malloc來生出空間,free來還回空間,以此方式產生的空間是不受系統控制的,因為自己必須自行管理是否刪除。

* 生命週期為建立 (malloc) 後一直到 (free) 才會還回此空間,因此不管你是使用main()中來生出此空間,還是在function()中來產生空間,只要用指標就可以參考到。
* 「有借就有還」,要了多少空間就要還回去多少空間,否則會造成memory leak
* 最好統一在main() init()這樣的函式中產生,不要在任意的function()中產生,記憶體比較好管理。
* 每個程式都有一定的配置空間,如果使用後不還回去的話,空間會被吃光光,可能程式執行到一半,就會出現無法配置的錯誤,因為之前借了都沒有還回去。
* 不受區塊或是scope控制,只要指向的指標沒有丟掉就可以了。
* 指向此空間開頭的指標不能丟失,否則的話,沒有辦法用free()還回去,一定會造成memory leak。

變數週期表

變數範疇圖

變數週期圖

2 意見:

    您好,之前就曾拜讀您的大作,獲益良多。

    不知文章裡的附圖是否存在呢?
    謝謝!

     

    圖片的部份很可惜,之前在轉換的時候遺失了,有興趣的話可以交換電郵相互學一下,我的電郵femc7488@gmail.com