面試官:static 全局變量和普通全局變量的區別是什么?
Static 全局變量和普通全局變量在 C 語言中的主要區別體現在鏈接屬性和作用域上。
1. 鏈接屬性
在 C 語言里有鏈接屬性這個概念,分文:內部鏈接和外部鏈接。
- 普通全局變量:具有外部鏈接(external linkage),即其他源文件可以通過extern聲明訪問該變量。
// file1.c
int globalVar = 10; // 普通全局變量
// file2.c
extern int globalVar; // 正確:可以訪問file1.c中的globalVar
- static 全局變量:具有內部鏈接(internal linkage),只能在定義它的源文件內訪問,其他文件無法通過 extern 引用。
// file1.c
static int staticVar = 20; // static全局變量
// file2.c
extern int staticVar; // 錯誤:無法訪問file1.c中的staticVar
2. 作用域
- 普通全局變量:作用域是整個程序(所有源文件),前提是其他文件正確使用extern聲明。
- static 全局變量:作用域僅限于定義它的源文件,其他文件不可見。
3. 用途與優勢
- 普通全局變量:適合在多個文件之間共享數據,但需謹慎使用,避免命名沖突。
- static 全局變量:用于隱藏實現細節,避免命名沖突,增強模塊化。例如:
// utils.c
static int counter = 0; // 僅在本文件內使用
void increment() { counter++; } // 其他文件無法直接修改counter
4. 存儲與生命周期
兩者相同:存儲于靜態存儲區。靜態存儲區包括初始化數據段(.data)和未初始化數據段(.bss) 。普通全局變量和 static 變量(無論是全局還是局部靜態)都在這里,生命周期都是整個程序運行期間,且默認初始化為零值。如果變量被顯式初始化了非零值,就放在.data 段;如果未初始化或初始化為零,則放在.bss 段。這樣能節省磁盤空間,因為.bss 段不存儲實際數據,只在程序加載時分配內存。
5. 總結
特性 | 普通全局變量 | static 全局變量 |
鏈接屬性 | 外部鏈接(可跨文件) | 內部鏈接(僅本文件) |
作用域 | 全局 | 文件內 |
防止命名沖突 | 弱 | 強(隱藏變量) |
頭文件中的使用 | 需用 | 避免在頭文件中定義 |
通過合理使用static,可以提高代碼的封裝性和安全性,減少全局命名空間的污染。