概念
靜態變數
靜態是一個變數的存儲類型,在一個變數的定義前加上關鍵字static,表示定義了一個存儲類型為靜態型的變數。
靜態變數採用的是靜態的存儲分配方式。靜態變數在程式運行一開始就被分配相應的記憶體空間,並且所分配的存儲空間在整個程式運行過程中自始至終歸該變數所有,直至程式結束。靜態變數是一種生存期為整個源程式的量。雖然離開定義它的函式後不能使用,但如再次調用定義它的函式時,它又可繼續使用,而且保存了前次被調用後留下的值。
靜態變數分為外部靜態變數和內部靜態變數兩種。
內部靜態變數
在局部變數的定義前面加上關鍵字static,就表示定義了一個內部靜態變數。由於內部靜態變數也是在函式內部定義的,一年春具有局部的作用域。但其靜態的特性決定了變數具有全局的生存期。
外部靜態變數
同理,在外部變數的定義前面加上關鍵字static,就表示定義了一個外部靜態變數。外部靜態變數具有全局的作用域和全局的生存期。更重要的是,static還將外部變數向其他檔案中進行作用範圍的擴展。即定義成static類型的外部變數將無法再使用extern將其作用範圍擴展到其他檔案中,而是被限制在了本身所在的檔案內。這使得多人在各自編寫的不同模組檔案中,可以各自定義同名的靜態變數而不受影響。從而給程式的模組化、通用性提供方便。
外部靜態變數性質
靜態變數的類型說明符是static。靜態變數當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變數。外部變數雖屬於靜態存儲方式,但不一定是靜態變數,必須由static 加以定義後才能成為靜態外部變數,或稱靜態全局變數。
外部變數的說明之前再冠以static 就構成了靜態的外部變數,靜態外部變數是一種靜態全局變數。全局變數本身就是靜態存儲方式,靜態全局變數當然也是靜態存儲方式。這兩者的區別雖在於非靜態全局變數的作用域是整個源程式,當一個源程式由多個源檔案組成時,非靜態的全局變數在各個源檔案中都是有效的。而靜態全局變數則限制了其作用域,即只在定義該變數的源檔案內有效,在同一源程式的其它源檔案中不能使用它。由於靜態全局變數的作用域局限於一個源檔案內,只能為該源檔案內的函式公用,因此可以避免在其它源檔案中引起錯誤。下面是外部靜態變數的性質:
(1)記憶體中的位置:靜態存儲區(靜態存儲區在整個程式運行期間都存在)
( 2)初始化:未經初始化的全局靜態變數會被程式自動初始化為0(自動對象的值是任意的,除非他被顯示初始化)
(3)作用域:全局靜態變數在聲明他的檔案之外是不可見的。準確地講從定義之處開始到檔案結尾。
(4)定義全局靜態變數的好處:
<1>不會被其他檔案所訪問,修改;
<2>其他檔案中可以使用相同名字的變數,不會發生衝突。
靜態變數(內部、外部)與全局變數差別
下表是外部靜態變數、內部靜態變數和全局變數三種變數在作用域、生命周期和初始化情況方面的比較:
| 外部靜態變數 | 內部靜態變數 | 全局變數 |
作用域
| 只在定義它的源檔案有效,同一程式的其他源檔案不能使用 | 所在源檔案,局部可用(所定義的{ }內有效) | 默認為所在源檔案;若其他檔案需要使用,用extern聲明 |
生命期
| 從定義到程式結束 | 從定義到程式結束 | 從定義到程式結束 |
初始化
| 自動賦值為0 | 自動賦值為0 | 自動賦值為0 |
注意:
1)在include頭檔案時,只需要當成將頭檔案中的代碼放到引用檔案中,同時,一個類的一個方法只有一份記憶體,與Java中相同。
2)所有未加static前綴的全局變數和函式都具有全局可見性,其它的源檔案也能訪問,如果加了static,就會對其它源檔案隱藏。