常量使用
靜态變量也可以用于存儲常數。具體來說,靜态變量(全局變量及彙編語言裡定義的符号亦同)可用const,constant或final(根據語言決定)等關鍵字标識,這時其值就會在編譯時(英語:Compiletime)設定,并且無法在運行時改變。編譯器通常将靜态常量與文本一起置于目标文件的文本區域,而非常量初始化數據則置于數據區;而如若有需要,有些編譯器還可選擇為其開辟專用區;為防止常數變量被錯誤的指針寫入複蓋,亦可在這塊區域啟用内存保護機制。
變量特點
靜态局部變量屬于靜态存儲方式,它具有以下特點:
(1)靜态局部變量在函數内定義,但不象自動變量那樣,當調用時就存在,退出函數時就消失。靜态局部變量始終存在着,也就是說它的生存期為整個源程序。
(2)靜态局部變量的生存期雖然為整個源程序,但是其作用域仍與自動變量相同,即隻能在定義該變量的函數内使用該變量。退出該函數後,盡管該變量還繼續存在,但不能使用它。
(3)允許對構造類靜态局部量賦初值。若未賦以初值,則由系統自動賦值。數值型變量自動賦初值0,字符型變量賦空字符。
(4)對基本類型的靜态局部變量若在說明時未賦以初值,則系統自動賦予0值。而對自動變量不賦初值,則其值是不定的。根據靜态局部變量的特點,可以看出它是一種生存期為整個源文件的量。雖然離開定義它的函數後不能使用,但如再次調用定義它的函數時,它又可繼續使用,而且保存了前次被調用後留下的值。因此,當多次調用一個函數且要求在調用之間保留某些變量的值時,可考慮采用靜态局部變量。雖然用全局變量也可以達到上述目的,但全局變量有時會造成意外的副作用,因此仍以采用局部靜态變量為宜。
給讀者一個簡單直白的例子(區别靜态局部變量和動态局部變量):
intfun(intn)
{
staticintf=1;/*請注意這行的修改*/這是static結果:
f=f*n;
return(f);
}
intmain()
{
inti;
for(i=1;i<=5;i++)
printf("%d!=%dn",i,fun(i));
}
=========================================================
intfun(intn)
{
intf=1;/*請注意這行的修改*/結果是:
f=f*n;
return(f);
}
intmain()
{
inti;
for(i=1;i<=5;i++)
printf("%d!=%dn",i,fun(i));
}
———————————————————————————————————————————————
下面是java例子:
publicclassStaticTest{
staticintf=1;//java聲明靜态變量要放到方法外面,結果和c的結果一樣
intfun(intn){
f=f*n;
return(f);
}
publicstaticvoidmain(String[]args){
StaticTestst=newStaticTest();
for(inti=1;i<=5;i++){
System.out.println(st.fun(i));
}
}
}
---------------------------------------------------------------------------------------------------------------
ModuleModule1
PublicaAsInteger‘未賦值的情況下a的值是0
EndModule
PublicClassForm1
PrivateSubForm1_Load(ByValsenderAsObject,ByValeAsSystem.EventArgs)HandlesMe.Load
a+=1
EndSub
PrivateSubButton3_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesButton3.Click
a+=1
MsgBox(a)’結果是2(0+1+1)因為是a是模塊級靜态全局變量,所以按按鈕3以後,直到關閉程序a的值都會是2
EndSub
EndClass
變量定義
全局變量(外部變量)的說明之前再冠以static就構成了靜态的全局變量。全局變量本身就是靜态存儲方式,靜态全局變量當然也是靜态存儲方式。
這兩者在存儲方式上并無不同。這兩者的區别雖在于非靜态全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜态的全局變量在各個源文件中都是有效的。而靜态全局變量則限制了其作用域,即隻在定義該變量的源文件内有效,在同一源程序的其它源文件中不能使用它。
由于靜态全局變量的作用域局限于一個源文件内,隻能為該源文件内的函數公用,因此可以避免在其它源文件中引起錯誤。從以上分析可以看出,把局部變量改變為靜态變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜态變量後是改變了它的作用域,限制了它的使用範圍。因此static這個說明符在不同的地方所起的作用是不同的。應予以注意。
在局部變量的說明前再加上static說明符就構成靜态局部變量。
例如:
staticinta,b;
staticfloatarray={1,2,3,4,5};
與自動變量與内存的關系
1.分配給全局變量的内存,一直到程序運行結束時才釋放。
2.對于在程序塊中申明的變量,在塊的入口處對其分配内存,在塊退出時釋放内存,則這種變量稱為自動變量。一直到程序結束時才釋放内存的稱為全局變量。
靜态變量的存活期
除範圍之外,變量還有存活期,在這一期間變量能夠保持它們的值。在應用程序的存活期内一直保持模塊級變量和公用變量的值。但是,對于Dim聲明的局部變量以及聲明局部變量的過程,僅當過程在執行時這些局部變量才存在。通常,當一個過程執行完畢,它的局部變量的值就已經不存在,而且變量所占據的内存也被釋放。當下一次執行該過程時,它的所有局部變量将重新初始化。
但可将局部變量定義成靜态的,從而保留變量的值。在過程内部用Static關鍵字聲明一個或多個變量,其用法和Dim語句完全一樣:
StaticDepth
例如,下面的函數将存儲在靜态變量Accumulate中的以前的運營總值與一個新值相加,以計算運營總值。
FunctionRunningTotal(num)
StaticApplesSold
ApplesSold=ApplesSold+num
RunningTotal=ApplesSold
EndFunction
如果用Dim而不用Static聲明ApplesSold,則以前的累計值不會通過調用函數保留下來,函數隻會簡單地返回調用它的那個相同值。
在模塊的聲明段聲明ApplesSold,并使它成為模塊級變量,由此也會收到同樣效果。但是,這種方法一旦改變變量的範圍,過程就不再對變量排他性存取。由于其它過程也可以訪問和改變變量的值,所以運營總值也許不可靠,代碼将更難于維護。
聲明所有的局部變量為靜态變量
為了使過程中所有的局部變量為靜态變量,可在過程頭的起始處加上Static關鍵字。例如:
StaticFunctionRunningTotal(num)
這就使過程中的所有局部變量都變為靜态,無論它們是用Static、Dim或Private聲明的還是隐式聲明的。可以将Static放在任何Sub或Funtion過程頭的前面,包括事件過程和聲明為Private的過程。
賦值問題
請比較一下兩個遞歸函數調用自己(即運行f1(f1())或f2(f2()))時的的運行結果。
intf1()
{
staticintn=0;//這裡聲明靜态局部變量n,如果不是第一次使用本函數,則此句不會執行(因為n是已經存在//着的,并且保留着上一次使用後的數據。)
f1();
printf("%d",++n);
}
=============================
intf2()
{
staticintn;//
n=0;//對n重新賦值為0;
f2();
printf("%d",++n);
}



















