C ------ static 關鍵字的作用
首先要理解生存周期與作用域的區別:
生存周期: 變量從定義到銷毀的時間範圍。存放在全局數據區的變量的生存周期存在於整個程序運行期間,而存放在棧中的數據則隨著函數等的作用域結束導致出棧而銷毀,除了靜態變量之外的局部變量都存放於棧中。
作用域: 變量的可見代碼域(塊作用域,函數作用域,類作用域,程序全局作用域)。
static變量是指靜態的變量,不管是在全局還是局部聲明的static變量都存放於程序的全局變量區域,所以它的生命周期是從程序開始到程序結束。但是static變量的作用域並不等同於它的生存周期,它的作用域決定於它被定義的位置。可以認為static變量的作用域<=生存周期。
舉一個局部聲明的例子。在函數test中聲明靜態變量i:
void test()
{
int m=3;
static int i=5;
}
局部變量m存放在棧中,當test函數結束,m將被銷毀;靜態變量i不存放在棧中,而是存放於程序的全局變量區域,因此隨著函數test的結束,它並不隨著出棧操作而被銷毀,它的生存周期存在於程序的整個運行期;然而m和i的作用域都僅存在於test函數中它們的定義之後,即test調用結束之後,m和i就不再可用,但是i仍存在於內存之中。
再舉一個全局聲明的例子。在文件A 中定義靜態變量j:
int n=3; //默認為extern
static int j=5; //聲明為static
全局變量和靜態變量j都存放於程序的全局數據區域,它們的生存周期都是程序的整個運行期,但是n的作用域為全局作用域,可以通過extern在其他文件中使用,而j只能在文件A中使用,例如在文件B中:
extern int n; //ok
extern int j; //error: j在文件B中不可見
int a=n;//ok:但這裏有個初始化先後的問題,具體參見參考一
int b=j;//error
也就是說,在聲明全局的static變量時,static沒有改變它的生存周期,也即存儲位置(因為全局變量本來就存儲在全局數據域),而是將變量的作用域限制在當前文件中。
中興通訊2012校招筆試題的一道問答題:
1. static全局變量與普通的全局變量有什麽區別 ?
全局變量(外部變量)的說明之前再冠以static 就構成了靜態的全局變量。
全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。
這兩者的區別在於非靜態全局變量的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。由於靜態全局變量的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。
static全局變量只初使化一次,防止在其他文件單元中被引用;
2. static局部變量和普通局部變量有什麽區別 ?
把局部變量改變為靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量後是改變了它的作用域,限制了它的使用範圍。
static局部變量只被初始化一次,下一次依據上一次結果值;
3. static函數與普通函數有什麽區別?
static函數與普通函數作用域不同,僅在本文件。只在當前源文件中使用的函數應該說明為內部函數(static修飾的函數),內部函數應該在當前源文件中說明和定義。對於可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件.
static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝
C ------ static 關鍵字的作用