作用域決定變數名稱可見範圍;生命週期決定變數儲存空間存在時間。兩者相關但不同。
| 類別 | 宣告位置 | 作用域範圍 | 生命週期 | 預設初始化 |
|---|---|---|---|---|
| 區域變數 | 函數/區塊內部 | 從宣告點至區塊結束 | 區塊執行期間 (棧上) | 無 (未定義值) |
| 全域變數 | 所有函數外部 | 全程式 (從宣告點起) | 程式全期 (靜態儲存區) | 零初始化 (0, '\0', nullptr) |
| 靜態區域變數 | 函數/區塊內 + static | 同區域變數 | 程式全期 | 零初始化 |
僅在宣告的區塊 {...} 內可見。未初始化值不定,必須手動初始化。
void func() {
int a = 10; // 初始化
{ int b = 20; } // b 作用域結束
// cout << b; // 錯誤
}
檔案層級宣告,跨函數可見。自動零初始化。
int g = 20; // 全域
int main() {
int g = 10; // 區域遮蔽全域
cout << g; // 10
cout << ::g; // 20 (作用域解析運算子)
}
⚠️ 盡量減少全域變數:耦合度高、難測試、執行緒不安全、命名衝突風險。優先用單例模式、依賴注入、命名空間管理共享狀態。
static 修飾區域變數:僅初始化一次,保持值跨越呼叫。
void counter() {
static int cnt = 0; // 程式啟動前零初始化,首次呼叫前動態初始化
cout << ++cnt << endl;
}
counter(); // 1
counter(); // 2
將全域實體包裹於命名空間,避免污染全域命名空間:
namespace MyProject {
int configVersion = 1;
void init() { ... }
}
// 使用
MyProject::init();
using MyProject::configVersion;
形式參數作用域為函數本體,生命週期為函數呼叫期間。傳值參數為區域副本;參考/指標參數指向實參儲存空間。
new 配置,delete 釋放。生命週期由程式設計師手動控制(或透過智慧型指標 RAII 管理)。非作用域概念,指標/參考可跨作用域存取。
int x = 0;、int x{0}; (C++11 統一初始化)。-Wuninitialized、靜態分析工具。const 變數必須初始化,且不可修改。static (區域持久)、thread_local (C++11 執行緒區域儲存)、inline 變數 (C++17 標頭檔定義) 管理共享狀態。