extern 的外部鏈接。// file1.c
static int g_count = 0; // 僅 file1 可見,外部 extern 無法引用
static void internal_init(); // 內部函數,防止符號衝突
等效於 C++ 的無名命名空間 namespace { ... },是**模組封裝**的基礎手段。
void counter() {
static int cnt = 0; // 僅初始化一次!後續調用保持上次值
printf("%d\n", ++cnt);
}
// 輸出: 1, 2, 3...
同靜態全域變數:限制鏈接性為內部,實現檔案級封裝。與儲存方式無關(函數代碼本就在代碼段)。
class Test {
static int shared_; // 聲明(類內)
int a_, b_;
public:
Test(int a, int b) : a_(a), b_(b) { shared_ = a + b; }
void print() const { cout << shared_ << endl; }
};
int Test::shared_ = 0; // 定義(類外,必須!分配記憶體)
Test::shared_ 或 obj.shared_ 訪問。class Test {
static int data_;
public:
static void printData() { cout << data_ << endl; } // 無 this 指標
static void helper() { printData(); } // 只能調用靜態成員
};
this 指標**,故不能直接訪問非靜態成員。obj.func() 或類名 Test::func() 調用。所有靜態儲存期變數(全域、static 區域、static 成員)若無顯式初始化,**保證零初始化**(0、NULL、0.0)。非靜態區域變數無此保證(值不定)。
| 維度 | static 全域/函數 | 普通全域/函數 |
|---|---|---|
| 鏈接性 | 內部 | 外部 |
| 跨檔案訪問 | 不可 | 可 |
| 符號衝突風險 | 無 | 有 |
| 維度 | static 區域變數 | 普通區域變數 |
| 儲存區 | 靜態區 | 棧 |
| 生命週期 | 程式全期 | 函數調用期間 |
| 值保持性 | 跨調用保持 | 每次重新初始化 |
| 執行緒安全 | 需自行加鎖 | 各執行緒獨立棧幀,天然隔離 |
thread_local (C++11) 隔離執行緒。inline static 在類內定義。static T& instance() { static T obj; return obj; } (Meyers Singleton) 利用 C++11 靜態區域變數執行緒安全初始化特性,簡潔高效。透徹掌握 static 在不同語境下的儲存期、鏈接性、作用域三重屬性,是寫出模組化、可維護、執行緒安全 C/C++ 代碼的關鍵基石。