C語言 static 與 const 關鍵字深度解析:作用域、存儲類別、指針應用
static 和 const 是 C 語言中最易混淆、功能最豐富的關鍵字。本文系統梳理它們的所有用法、區別與最佳實踐。
一、static 關鍵字三大用法
1. 修飾局部變量 → 靜態存儲期
void counter() {
static int count = 0; // 僅初始化一次,保留值
printf("%d ", count++);
}
int main() {
counter(); // 0
counter(); // 1
counter(); // 2
}
- 存儲在靜態數據區(非棧)
- 生命周期 = 程序運行期
- 作用域仍限於代碼塊內
2. 修飾全局變量/函數 → 內部鏈接
// file1.c
static int global = 10; // 僅本文件可見
static void helper() { ... } // 僅本文件可調用
// file2.c
// extern int global; // 鏈接錯誤:找不到符號
// helper(); // 編譯錯誤:隱式聲明
3. 修飾函數參數(C99 靜態數組參數)
void func(int arr[static 10]); // 承諾傳入至少 10 元素數組
二、const 關鍵字完整指南
1. 修飾基本類型 → 唯讀變量
const int MAX = 100; // 編譯期常量(C++),運行期只讀變量(C)
const int *p = &MAX; // 指向常量的指針
// *p = 200; // 錯誤
2. 指針與 const 的四種組合
| 聲明 | 口訣 | 指針可改 | 內容可改 |
const int *p | const 在 * 左 → *p 是常量 | ✅ | ❌ |
int *const p | const 在 * 右 → p 是常量 | ❌ | ✅ |
const int *const p | 雙 const → 都不可改 | ❌ | ❌ |
int const *p | 等價 const int *p | ✅ | ❌ |
3. 函數參數與返回值
三、static vs const 核心區別
| 維度 | static | const |
| 核心語義 | 存儲期/鏈接性 | 只讀/不可變 |
| 影響內存佈局 | 是(靜態區 vs 棧) | 否(編譯期檢查) |
| 可組合使用 | static const int x = 10; | 同上 |
| 典型用途 | 單例、計數器、文件封裝 | 常量、只讀參數、字面量 |
四、最佳實踐清單
- 文件內部函數/變量默認加
static
- 指針參數只讀必加
const
- 字面量字符串必用
const char *
- 定義常量優先
#define / enum / static const
- 避免返回指向棧內存的指針,靜態局部變量除外