【分享】C語言初學者入門講座 第十講 函數(5)@ngchk.com
【分享】C語言初學者入門講座 第十講 函數(5)
C語言初學者入門講座 第十講 函數(5)
三、靜態變數
靜態變數的類型說明符是static。 靜態變數當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變數, 例如外部變數雖屬於靜態存儲方式,但不一定是靜態變數,必須由 static加以定義後才能成爲靜態外部變數,或稱靜態總體變數。 對於自動變數,前面已經介紹它屬於動態存儲方式。 但是也可以用static定義它爲靜態自動變數,或稱靜態局部變數,從而成爲靜態存儲方式。
由此看來, 一個變數可由static進行再說明,並改變其原有的存儲方式。
1. 靜態局部變數
在局部變數的說明前再加上static說明符就構成靜態局部變數。
例如:
static int a,b;
static float array[5]={1,2,3,4,5};
靜態局部變數屬於靜態存儲方式,它具有以下特點:
(1)靜態局部變數在函數內定義,但不象自動變數那樣,當調用時就存在,退出函數時就消失。靜態局部變數始終存在著,也就是說它的生存期爲整個根源程式。
(2)靜態局部變數的生存期雖然爲整個根源程式,但是其作用域仍與自動變數相同,即只能在定義該變數的函數內使用該變數。退出該函數後, 儘管該變數還繼續存在,但不能使用它。
(3)允許對構造類靜態局部量賦初值。在陣列一章中,介紹陣列初始化時已作過說明。若未賦以初值,則由系統自動賦以0值。
(4)對基本類型的靜態局部變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變數不賦初值,則其值是不定的。 根據靜態局部變數的特點, 可以看出它是一種生存期爲整個根源程式的量。雖然離開定義它的函數後不能使用,但如再次調用定義它的函數時,它又可繼續使用, 而且保存了前次被調用後留下的值。 因此,當多次調用一個函數且要求在調用之間保留某些變數的值時,可考慮採用靜態局部變數。雖然用總體變數也可以達到上述目的,但總體變數有時會造成意外的副作用,因此仍以採用局部靜態變數爲宜。
[例5.15]
main()
{
int i;
void f(); /*函數說明*/
for(i=1;i<=5;i++)
f(); /*函數調用*/
}
void f() /*函數定義*/
{
auto int j=0;
++j;
printf("%d\n",j);
}
程式中定義了函數f,其中的變數j 說明爲自動變數並賦予初始值爲0。當main中多次調用f時,j均賦初值爲0,故每次輸出值均爲1。現在把j改爲靜態局部變數,程式如下:
main()
{
int i;
void f();
for (i=1;i<=5;i++)
f();
}
void f()
{
static int j=0;
++j;
printf("%d\n",j);
}
void f()
{
static int j=0;
++j;
printf("%d/n",j);
}
由於j爲靜態變數,能在每次調用後保留其值並在下一次調用時繼續使用,所以輸出值成爲累加的結果。讀者可自行分析其執行過程。
2.靜態總體變數
總體變數(外部變數)的說明之前再冠以static 就構成了靜態的總體變數。總體變數本身就是靜態存儲方式, 靜態總體變數當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態總體變數的作用域是整個根源程式, 當一個根源程式由多個原始檔案組成時,非靜態的總體變數在各個原始檔案中都是有效的。 而靜態總體變數則限制了其作用域, 即只在定義該變數的原始檔案內有效, 在同一根源程式的其他原始檔案中不能使用它。由於靜態總體變數的作用域局限於一個原始檔案內,只能爲該原始檔案內的函數公用, 因此可以避免在其他原始檔案中引起錯誤。從以上分析可以看出, 把局部變數改變爲靜態變數後是改變了它的存儲方式即改變了它的生存期。把總體變數改變爲靜態變數後是改變了它的作用域, 限制了它的使用範圍。因此static 這個說明符在不同的地方所起的作用是不同的。應予以注意。
四、寄存器變數
上述各類變數都存放在記憶體內, 因此當對一個變數頻繁讀寫時,必須要反復訪問內記憶體,從而花費大量的存取時間。 爲此,C語言提供了另一種變數,即寄存器變數。這種變數存放在CPU的寄存器中,使用時,不需要訪問記憶體,而直接從寄存器中讀寫, 這樣可提高效率。寄存器變數的說明符是register。 對於迴圈次數較多的迴圈控制變數及循環體內反復使用的變數均可定義爲寄存器變數。
[例5.16]
求∑200i=1imain()
{
register i,s=0;
for(i=1;i<=200;i++)
s=s+i;
printf("s=%d\n",s);
}
本程式迴圈200次,i和s都將頻繁使用,因此可定義爲寄存器變數。對寄存器變數還要說明以下幾點:
1. 只有局部自動變數和形式參數才可以定義爲寄存器變數。因爲寄存器變數屬於動態存儲方式。凡需要採用靜態存儲方式的量不能定義爲寄存器變數。
2. 在Turbo C,MS C等微機上使用的C語言中, 實際上是把寄存器變數當成自動變數處理的。因此速度並不能提高。 而在程式中允許使用寄存器變數只是爲了與標準C保持一致。3. 即使能真正使用寄存器變數的機器,由於CPU 中寄存器的個數是有限的,因此使用寄存器變數的個數也是有限的。
三、靜態變數
靜態變數的類型說明符是static。 靜態變數當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變數, 例如外部變數雖屬於靜態存儲方式,但不一定是靜態變數,必須由 static加以定義後才能成爲靜態外部變數,或稱靜態總體變數。 對於自動變數,前面已經介紹它屬於動態存儲方式。 但是也可以用static定義它爲靜態自動變數,或稱靜態局部變數,從而成爲靜態存儲方式。
由此看來, 一個變數可由static進行再說明,並改變其原有的存儲方式。
1. 靜態局部變數
在局部變數的說明前再加上static說明符就構成靜態局部變數。
例如:
static int a,b;
static float array[5]={1,2,3,4,5};
靜態局部變數屬於靜態存儲方式,它具有以下特點:
(1)靜態局部變數在函數內定義,但不象自動變數那樣,當調用時就存在,退出函數時就消失。靜態局部變數始終存在著,也就是說它的生存期爲整個根源程式。
(2)靜態局部變數的生存期雖然爲整個根源程式,但是其作用域仍與自動變數相同,即只能在定義該變數的函數內使用該變數。退出該函數後, 儘管該變數還繼續存在,但不能使用它。
(3)允許對構造類靜態局部量賦初值。在陣列一章中,介紹陣列初始化時已作過說明。若未賦以初值,則由系統自動賦以0值。
(4)對基本類型的靜態局部變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變數不賦初值,則其值是不定的。 根據靜態局部變數的特點, 可以看出它是一種生存期爲整個根源程式的量。雖然離開定義它的函數後不能使用,但如再次調用定義它的函數時,它又可繼續使用, 而且保存了前次被調用後留下的值。 因此,當多次調用一個函數且要求在調用之間保留某些變數的值時,可考慮採用靜態局部變數。雖然用總體變數也可以達到上述目的,但總體變數有時會造成意外的副作用,因此仍以採用局部靜態變數爲宜。
[例5.15]
main()
{
int i;
void f(); /*函數說明*/
for(i=1;i<=5;i++)
f(); /*函數調用*/
}
void f() /*函數定義*/
{
auto int j=0;
++j;
printf("%d\n",j);
}
程式中定義了函數f,其中的變數j 說明爲自動變數並賦予初始值爲0。當main中多次調用f時,j均賦初值爲0,故每次輸出值均爲1。現在把j改爲靜態局部變數,程式如下:
main()
{
int i;
void f();
for (i=1;i<=5;i++)
f();
}
void f()
{
static int j=0;
++j;
printf("%d\n",j);
}
void f()
{
static int j=0;
++j;
printf("%d/n",j);
}
由於j爲靜態變數,能在每次調用後保留其值並在下一次調用時繼續使用,所以輸出值成爲累加的結果。讀者可自行分析其執行過程。
2.靜態總體變數
總體變數(外部變數)的說明之前再冠以static 就構成了靜態的總體變數。總體變數本身就是靜態存儲方式, 靜態總體變數當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態總體變數的作用域是整個根源程式, 當一個根源程式由多個原始檔案組成時,非靜態的總體變數在各個原始檔案中都是有效的。 而靜態總體變數則限制了其作用域, 即只在定義該變數的原始檔案內有效, 在同一根源程式的其他原始檔案中不能使用它。由於靜態總體變數的作用域局限於一個原始檔案內,只能爲該原始檔案內的函數公用, 因此可以避免在其他原始檔案中引起錯誤。從以上分析可以看出, 把局部變數改變爲靜態變數後是改變了它的存儲方式即改變了它的生存期。把總體變數改變爲靜態變數後是改變了它的作用域, 限制了它的使用範圍。因此static 這個說明符在不同的地方所起的作用是不同的。應予以注意。
四、寄存器變數
上述各類變數都存放在記憶體內, 因此當對一個變數頻繁讀寫時,必須要反復訪問內記憶體,從而花費大量的存取時間。 爲此,C語言提供了另一種變數,即寄存器變數。這種變數存放在CPU的寄存器中,使用時,不需要訪問記憶體,而直接從寄存器中讀寫, 這樣可提高效率。寄存器變數的說明符是register。 對於迴圈次數較多的迴圈控制變數及循環體內反復使用的變數均可定義爲寄存器變數。
[例5.16]
求∑200i=1imain()
{
register i,s=0;
for(i=1;i<=200;i++)
s=s+i;
printf("s=%d\n",s);
}
本程式迴圈200次,i和s都將頻繁使用,因此可定義爲寄存器變數。對寄存器變數還要說明以下幾點:
1. 只有局部自動變數和形式參數才可以定義爲寄存器變數。因爲寄存器變數屬於動態存儲方式。凡需要採用靜態存儲方式的量不能定義爲寄存器變數。
2. 在Turbo C,MS C等微機上使用的C語言中, 實際上是把寄存器變數當成自動變數處理的。因此速度並不能提高。 而在程式中允許使用寄存器變數只是爲了與標準C保持一致。3. 即使能真正使用寄存器變數的機器,由於CPU 中寄存器的個數是有限的,因此使用寄存器變數的個數也是有限的。
|