變量是程序操作數據的句柄,其行為由作用域(可見範圍)與存儲類別(生命週期、內存區域)共同決定。本文系統梳理全局/局部、靜態/動態/寄存器/外部等屬性組合,並對應內存佈局(靜態區、棧、寄存器)。
| 維度 | 分類 | 關鍵字/默認 |
|---|---|---|
| 作用域 | 全局變量 | 文件級,函數外定義 |
| 局部變量 | 塊級,函數/塊內定義 | |
| 存儲類別 | 自動 (auto) | 局部默認,棧分配,隨塊銷毀 |
| 靜態 (static) | 靜態區分配,程序全程存在,保持值 | |
| 寄存器 (register) | 請求寄存器存儲,極速訪問,無地址 | |
| 外部 (extern) | 聲明外部定義,擴展作用域 | |
| 動態分配 (malloc/free) | 堆區,手動管理生命週期 |
static 全局、static 局部auto 局部變量、函數形參register 變量(編譯器可拒絕降級為 auto)malloc/new 分配,free/delete 釋放以上均屬用戶態內存,受進程虛擬地址空間管理。
塊內聲明默認即 auto,棧上分配,塊結束自動銷毀。auto int a; 等價 int a;。現代 C++11 賦予 auto 新意(類型推導),C 語言無此特性。
static int count = 0;。僅初始化一次(編譯期/加載期),調用間保持值,僅在所在塊可見。static int g_var;。內部鏈接,僅本文件可見,避免符號衝突。提示編譯器將熱點局部變量/參數放入 CPU 寄存器,無法取址(&var 非法)。現代編譯器優化極強,通常自動決定,手動 register 多為文檔意圖。
// a.c 定義 int g; → // b.c extern int g; 使用extern 聲明extern int foo(); 等價 int foo();(隱式 extern)| 聲明位置/關鍵字 | 存儲區 | 生命週期 | 作用域 | 鏈接屬性 |
|---|---|---|---|---|
| 文件級 無 static | 靜態區 | 程序全程 | 全局(文件級) | 外部鏈接 |
| 文件級 static | 靜態區 | 程序全程 | 文件內部 | 內部鏈接 |
| 塊內 無 static | 棧 | 塊執行期間 | 塊內 | 無鏈接 |
| 塊內 static | 靜態區 | 程序全程 | 塊內 | 無鏈接 |
| 塊內 register | 寄存器/棧 | 塊執行期間 | 塊內 | 無鏈接 |
| extern 聲明 | 同定義處 | 同定義處 | 聲明所在文件 | 外部鏈接 |
static 局部(單線程安全)static 限制可見性extern 聲明,.c 中唯一定義register,但信任編譯器優化malloc/free,防洩漏/雙重釋放