儲存類別決定變數的作用域、連結屬性與儲存期(生命週期)。不同組合形成不同的儲存類別。
{...} 內定義,從定義處至區塊結束可見。函數參數也屬此類(隸屬函數本體區塊)。C99 允許在區塊任意位置宣告。goto 標籤。static 修飾檔案作用域變數)。malloc()/free() 管理的堆疊記憶體。區塊內預設為 auto(可省略)。迴圈/判斷敘述隱含區塊亦適用。
register 僅為請求,編譯器可能忽略。受限於暫存器大小與數量,無法取址(&)。
static 修飾區塊內變數:靜態儲存期、區塊作用域、無連結。程式載入時已就位,保留值跨越函數呼叫。
函數外部定義即為外部變數。其他檔案用 extern 宣告引用。定義宣告配置記憶體並可初始化(僅一次);參考宣告用 extern 告知編譯器別處有定義。未初始化的外部變數自動歸零。
檔案作用域加 static:僅限本檔案函數使用,隱藏於連結器。
| 關鍵字 | 用途 |
|---|---|
| auto | 區塊作用域自動變數(預設) |
| register | 區塊作用域,請求暫存器,不可取址 |
| static | 區塊內:靜態儲存期;檔案層級:內部連結 |
| extern | 宣告外部定義的變數/函數 |
| typedef | 型別別名,語法歸屬此類但與儲存無關 |
單一宣告中只能出現一個儲存類別說明符。
函數預設外部連結(可跨檔案呼叫),加 static 限制為內部連結(僅本檔案可見)。
double *ptd = (double*)malloc(30 * sizeof(double));
if (ptd) { /* 使用 */ free(ptd); }
malloc 依位元組配置,成功返回起始位址,失敗返回 NULL。每次 malloc 應對應一次 free,釋放非 malloc 記憶體導致未定義行為。原型在 <stdlib.h>。標準庫提供 EXIT_SUCCESS/EXIT_FAILURE 作為 exit() 參數。
自動變數記憶體自動管理;靜態變數固定;唯動態配置記憶體若不 free 會持續增長,造成記憶體洩漏。
long *newmem = (long*)calloc(100, sizeof(long));
calloc(n, size) 配置 n*size 位元組並全數歸零。同樣用 free() 釋放。
malloc:動態儲存期,可跨函數傳遞指標,靈活但需手動管理。自動變數使用堆疊(LIFO);動態配置使用堆積。
C99 規定限定詞冪等:const const int n = 6; 等同 const int n = 6;。
告訴編譯器:該變數可能被程式外部代理(硬體暫存器、中斷服務程式、多執行緒共享記憶體)修改,禁止優化掉存取。可同時為 const volatile(程式唯讀,硬體可寫)。
僅用於指標,指明該指標是存取某資料物件的唯一且初始途徑,幫助編譯器優化(如避免別名分析)。
int *restrict restar = (int*)malloc(10 * sizeof(int)); // 唯一存取路徑
int *par = ar; // 非唯一,不可加 restrict
void *memcpy(void *restrict s1, void *restrict s2, size_t n);
// s1、s2 不重疊,編譯器可積極優化