C語言複習篇之儲存類、連結和記憶體管理
儲存類、連結和記憶體管理
對儲存類、記憶體管理這方面的學習,能夠讓我們更加的理解程式的一個執行過程,理解程式在執行中的具體機制和它的實現方法。雖然對於寫程式碼本身並沒有太大的幫助,但是它能夠使得我們更好的理解程式,更容易去判斷程式是否能按我們的意願來實現,或者說讓我們糾錯更容易的知道是哪裡出了問題。
當然,複習的第一步依然是概念:
1.儲存型別
C語言中的儲存型別有下面幾個關鍵字:auto、static、register、extern。
auto:自動儲存類,由系統自動分配棧儲存空間,使用者不用操心。這種型別的變數是區域性於某個程式範圍內的,只能在某個程式範圍內使用,一般在函式體內,定義變數的預設方式就是屬於auto類變數。
static:靜態儲存類,既可以在函式體外也可以在函式體內定義,它在記憶體中是以固定地址存放的,在整個程式的執行過程中它都不會消失,並且static型別的變數只被初始化一次,且變數的值具有繼承性。舉個例子:
- voidfunc(void)
- {
- inti=0;
- i+=1;
- printf("%d\n",i);
- }
- intmain(void)
- {
- func();
- func();
- func();
- return0;
- }
執行結果:1,1,1
但是如果定義是這樣的:static int i = 0;結果就不一樣了,變成了1,2,3 。我們可以看到加了static關鍵字之後,每次呼叫函式func不會重複賦值而是延續上次運算的結果。
register:暫存器儲存型別,這種型別是比較牛的,因為不是你寫了register關鍵字它就會變成暫存器型別的變數,這是要看“心情”的,若是“心情”不好就會直接降級成為auto型變數。我們知道暫存器內執行速度是很快的,所以資源就比較寶貴,你定義了這樣一個變數之後,編譯器會自動判斷是否需要滿足你。因此對於暫存器變數的定義一般是使用頻率比較高的變數。
extern:外部儲存型別,用於外部變數的宣告,它的作用範圍是從定義開始到程式執行結束,它對於變數的型別和值是沒有改變的許可權的,因為extern關鍵字是用於宣告而不是定義。
宣告 | 定義 |
可以多次宣告 | 只能定義一次 |
不分配記憶體,不可初始化 | 分配記憶體空間,可以初始化 |
定義是特殊的宣告 |
2.作用域
程式碼塊作用域:在程式碼塊中({.....}之內的變數)定義的變數的作用的範圍。如:區域性變數,static區域性變數。
函式原型作用域:函式宣告(int fun(int x),小括號內的範圍)使用變數作用的範圍。
檔案作用域:在所有函式之外定義的變數的作用的範圍,又分為本檔案作用域(全域性變數static,函式static)和多檔案作用域(全域性變數和函式)。
3.連結
連結型別其實是和作用域對應起來的。
空連結:具有程式碼塊作用域和函式作用域的變數是空連結。
內部連結:具有檔案作用域的變數,它可以在一個檔案的任何地方使用。
外部連結:具有檔案作用域的變數,它可以在一個多檔案程式的任何地方使用。
4.儲存期
靜態儲存期,從變數定義開始到整個程式執行結束。
自動儲存期:棧裡定義的變數(由系統分配維護),程式進入這些變數的程式碼塊時,將為這些變數分配記憶體,退出時釋放記憶體。
動態儲存期:堆裡定義的變數,使用者自己定義,malloc( )開始到free ( )或者退出程式碼塊結束。
下面的總結和一個例子:
- inta;//全域性變數,靜態儲存期,外部連結,多檔案作用域
- staticintb;//全域性變數,靜態儲存期,內部連結,本檔案作用域
- voidfun(void)
- {
- intx;//區域性變數,自動儲存期,空連結,程式碼塊作用域
- staticinty;//區域性變數,靜態儲存期,空連結,程式碼塊作用域
- }
- intmain(void)
- {
- ....
- ....
- return0
- }
程式碼分析比較:
- A: B:
- int main(void) int main(void)
- { {
- char *p = "abcdefg"; char p[]="abcdefg";
- *p = ‘x’; *p = ‘x’;
- printf("%s\n",p); printf("%s\n",p);
- return 0; return 0;
- } }
- //A 錯誤,B正確。
以上程式碼為什麼會有這樣的結果呢?這就是一個儲存位置的問題了,程式碼A中字串“abcdefg”儲存於常量區只讀資料段,因此是不能改變它的,試圖改變它的結果只有一個段錯誤;而程式碼B就不同了,陣列元素是在棧中分配記憶體的,可以進行改變等操作。
網上下載的兩個圖表:
轉載於:https://blog.51cto.com/doublewen/765202