原文地址:http://blog.csdn.net/yunyun1886358/article/details/5632087
今天在論壇上看到有朋友發帖問道:既然靜態全局變量與全局變量都存儲在全局數據區,爲什麼作用域卻不一樣呢?也許答案非常簡單:C++就是這麼規定的,靜態全局變量與全局變量的唯一區別就是作用域不同。
對一個C++變量來說,有兩個屬性非常重要:作用域和生命週期,它們從兩個不同的維度描述了一個變量--時間和空間。顧名思義,作用域就是一個變量可以被引用的範圍,如:全局作用域、文件作用域、局部作用域;而生命週期就是這個變量可以被引用的時間段。不同生命週期的變量,在程序內存中的分佈位置是不一樣的。一個程序的內存分爲代碼區、全局數據區、堆區、棧區,不同的內存區域,對應不同的生命週期。
有很多方法來指定一個變量的作用域和生命週期。最常見的,如:{ }、static修飾符等。下面按照作用域與生命週期來對變量做一個分類:
全局變量
- 作用域:全局作用域(全局變量只需在一個源文件中定義,就可以作用於所有的源文件。)
- 生命週期:程序運行期一直存在
- 引用方法:其他文件中要使用必須用extern 關鍵字聲明要引用的全局變量。
- 內存分佈:全局數據區
- 注意:如果在兩個文件中都定義了相同名字的全局變量,連接出錯:變量重定義
- 例子:
- //defime.cpp
- int g_iValue = 1;
- //main.cpp
- extern int g_iValue;
- int main()
- {
- cout << g_iValue;
- return 0;
- }
全局靜態變量
- 作用域:文件作用域(只在被定義的文件中可見。)
- 生命週期:程序運行期一直存在
- 內存分佈:全局數據區
- 定義方法:static關鍵字,const 關鍵字
- 注意:只要文件不互相包含,在兩個不同的文件中是可以定義完全相同的兩個靜態變量的,它們是兩個完全不同的變量
- 例子:
- const int iValue_1;
- static const int iValue_2;
- static int iValue_3;
- int main()
- {
- return 0;
- }
靜態局部變量
- 作用域:局部作用域(只在局部作用域中可見)
- 生命週期:程序運行期一直存在
- 內存分佈:全局數據區
- 定義方法:局部作用域用中用static定義
- 注意:只被初始化一次,多線程中需加鎖保護
- 例子:
- void function()
- {
- static int iREFCounter = 0;
- }
局部變量
- 作用域:局部作用域(只在局部作用域中可見)
- 生命週期:程序運行出局部作用域即被銷燬
- 內存分佈:棧區
- 注意:auto指示符標示
還有一點要說明,掌握static關鍵字的使用很關鍵。以下是引用別人的一些經驗之談:
Tips:
- 若全局變量僅在單個C文件中訪問,則可以將這個變量修改爲靜態全局變量,以降低模塊間的耦合度;
- 若全局變量僅由單個函數訪問,則可以將這個變量改爲該函數的靜態局部變量,以降低模塊間的耦合度;
- 設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,需要考慮重入問題,因爲他們都放在靜態數據存儲區,全局可見;
- 如果我們需要一個可重入的函數,那麼,我們一定要避免函數中使用static變量(這樣的函數被稱爲:帶“內部存儲器”功能的的函數)
- 函數中必須要使用static變量情況:比如當某函數的返回值爲指針類型時,則必須是static的局部變量的地址作爲返回值,若爲auto類型,則返回爲錯指針。
來CSDN很久了,一直都想寫點東西,今天終於出手了。水平有限,只能跟大家分享一些基礎知識的總結,以共勉,共同提升。