四大儲存類別對比
| 類別 | 關鍵字 | 作用域 | 生命週期 | 預設初值 | 儲存區 |
| 全域變數 | (無) | 全檔案 (extern 可跨檔) | 程式啟動~結束 | 0 | 資料段 (.data/.bss) |
| 區域變數 | (無)/auto | 區塊 { } | 進入區塊~離開區塊 | 未定義 (垃圾值) | 堆疊 |
| 靜態全域 | static | 僅本檔案 (內部連結) | 程式啟動~結束 | 0 | 資料段 |
| 靜態區域 | static | 區塊 { } | 程式啟動~結束 | 0 | 資料段 |
| 暫存器 | register | 區塊 | 區塊 | 垃圾值 | CPU 暫存器 (建議) |
程式碼驗證三種 static 行為
1. 靜態全域變數 (檔案作用域 static)
static int g_count = 0; // 僅本 .c 可見
void func() { g_count++; }
2. 區域變數 (預設 auto)
void func() {
int count = 0; // 每次呼叫重新建立、銷毀
for(int i=0;i<10;i++) count++;
printf("%d ", count); // 每次印 1
}
3. 靜態區域變數 (關鍵:只初始化一次!)
void func() {
static int count = 0; // 程式啟動時初始化 0,之後保持值
for(int i=0;i<10;i++) count++;
printf("%d ", count); // 印 1 2 3 ... 10
}
核心區別總結
- 區域變數:每次呼叫重置,適合暫時計算。
- 靜態區域變數:跨呼叫保持狀態,適用於計數器、單例模式、快取、遞迴深度追蹤。
- 靜態全域/函數:隱藏實作細節**,避免符號衝突,模組化關鍵。
- 全域變數:慎用,造成耦合、難測試、執行緒不安全。
記憶體佈局圖示
高位址
| 堆疊 (區域、參數、返回位址) | 向下增長
| ... |
| 堆 (malloc/free) | 向上增長
| BSS (未初始化全域/static) |
| DATA (已初始化全域/static) |
| 程式碼段 (.text) |
低位址