一、存儲類
描述一個變量(一個數據對象):存儲週期、作用域、鏈接。
作用域:一個C變量的作用域可以是代碼塊作用域(在函數內部代碼塊中定義的變量、形參,稱爲局部變量),函數原型作用域(從變量定義處一直到原型聲明的末尾),或者文件作用域(一個在所有函數之外定義的變量,從定義處到包含定義的文件結尾處都可見,稱爲全局變量),函數作用域(只適應於goto語句使用的標籤),函數作用域意味着一個特定函數中的goto標籤對該函數中任何地方的代碼都是可見的,無論該標籤出現在哪一個代碼塊中。
鏈接:一個C變量具有以下鏈接之一,外部鏈接,內部鏈接或空鏈接。
具有代碼塊作用域和函數原型作用域的變量是空鏈接,由定義所在的代碼塊和函數原型所私有
具有外部鏈接的變量可以在多文件程序的任何地方使用,多個文件可有共享。
具有內部鏈接的變量可以在一個文件的任何地方使用,歸該文件私有。
具有文件作用域的變量可能是內部鏈接或者外部鏈接。
如果一個具有文件作用域的變量用static修飾,則是內部鏈接,否則是外部鏈接。
存儲時期:一個C變量具有以下兩種存儲時期之一,靜態存儲時期(在程序執行期間一直存在)和自動存儲時期
靜態存儲時期:在程序執行期間一直存在。具有文件作用域(不管是內部鏈接還是外部鏈接)的變量具有此存儲週期,注意對於具有文件作用域的變量,static標明連接類型不是存儲時期。
自動存儲時期:具有代碼塊作用域的變量一般是自動存儲週期。在程序進入定義的變量代碼塊中時在棧中分配內存,退出時釋放內存。
5種存儲類
存儲類
|
時期 |
作用域 |
鏈接 |
聲明方式 |
自動 |
自動 |
代碼塊 |
空 |
代碼塊內 |
寄存器 |
自動 |
代碼塊 |
空 |
代碼塊內,使用關鍵字register |
具有外部鏈接的靜態 |
靜態 |
文件 |
外部 |
所有函數之外 |
具有內部鏈接的靜態 |
靜態 |
文件 |
內部 |
所有函數之外,使用關鍵字static |
空鏈接的靜態 |
靜態 |
代碼塊 |
空 |
代碼塊內,使用關鍵字static |
自動變量:用auto修飾或者不修飾就默認屬於自動存儲類的變量具有自動存儲週期、代碼塊作用域、空鏈接。在默認下,在代碼快或者函數的頭部定義的任意變量都屬於自動存儲類。
如果在內層中使用和外層一樣名字的變量,則內層會覆蓋外層變量,在程序離開內層代碼塊時,外部變量就恢復了其作用和之前的值。
對於自動變量,除非顯示的初始化,否則不會自動初始化。
寄存器變量:通過register聲明,放在寄存器而非內存中,所以無法獲得其地址。注意,有時候雖然請求了把變量放於寄存器中,但是由於寄存器的個數,並不一定能滿足,所以寄存器變量就成爲了普通變量,不過依然不能對其取址。
具有代碼塊作用域的靜態變量:通過static修飾,如果不現實對其初始化,則自動初始化爲0(提供了靜態時期),在代碼塊內聲明(提供了代碼塊作用域和空鏈接),創建具有代碼塊作用域兼具靜態存儲的局部變量。這些變量具有代碼塊作用域,空鏈接,靜態存儲時期。變量一旦被定義便一直存在直到程序結束。
Int main(void)
{
Int count;
For(count = 1;conut < 4;count ++)
{printf(”count = %d\n”,count);
F();}
Return 0;
}
Void F(void)
{
Int fade = 1;
Static int stay = 1;
Printf(“fade = %d and stay = %d\n”,fade++,stay++);
}
結果:
Count = 1
Fade = 1 andstay = 1;
Count = 2
Fade = 1 andstay = 2;
Count = 3
Fade = 1 and stay = 3;
這是因爲靜態變量和外部變量在程序調入內存時已經就位了,把這個語句放在f()中是爲了告訴編譯器只有函數f()能看到該變量。
具有外部鏈接的靜態變量:具有文件作用域、外部鏈接、靜態時期(外部存儲類,外部變量)。
額外說明,外部變量只可進行一次初始化,而且在定義的時候。
具有內部鏈接的靜態變量:用static在所有函數的外部進行定義來創建,靜態存儲時期、文件作用域、內部鏈接。
二、存儲類說明符
Auto 標明一個變量具有自動存儲時期,該說明符只能用在具有代碼塊作用域的變量聲明中。
Register 只能用在具有代碼塊作用域的變量。請求一個變量存儲在寄存器中一邊快速使用,但是不能獲得改變量的地址。
Static 用於具有代碼塊作用域的變量聲明時,使該變量具有靜態存儲時期,從而得以在程序運行期間存在並保留其值,變量仍保留代碼塊作用域和空鏈接。若用於具有文件作用域的變量聲明時,使該變量具有內部鏈接。
Extern 表明在聲明一個在其他地方定義了的變量。
Const 將數據定爲不變的,在只能定義聲明,以後不可改變其值。在指針中使用時,const的位置決定是指針本身不變還是指針指向的數據不變。
Volatile 說明數據除了可以被程序修改外還可以被其他代理修改,主要用於編譯器優化。
Restrict 只能用於修飾指針,限定的指針被認爲是提供了對其所在指向的數據塊的唯一訪問途徑。