函數的存儲類型
『壹』 c語言中,函數的隱含存儲類別及形參的默認存儲類別分別是
c語言中,函數的隱含存儲類別是extern
形參的默認存儲類別是auto
『貳』 C語言中函數的隱含存儲類型
auto
自動存儲類別
關於動態存儲方式與靜態動態存儲方式
從變數的作用域(即從空間)角度來分,可以分為全局變數和局部變數。
從另一個角度,從變數值存在的作時間(即生存期)角度來分,可以分為靜態存儲方式和動態存儲方式。
靜態存儲方式:是指在程序運行期間分配固定的存儲空間的方式。
動態存儲方式:是在程序運行期間根據需要進行動態的分配存儲空間的方式。
用戶存儲空間可以分為三個部分:
程序區;
靜態存儲區;
動態存儲區。
全局變數全部存放在靜態存儲區,在程序開始執行時給全局變數分配存儲區,程序行完畢就釋放。在程序執行過程中它們占據固定的存儲單元,而不動態地進行分配和釋放。
動態存儲區存放以下數據:
函數形式參數;
自動變數(未加static聲明的局部變數);
函數調用實的現場保護和返回地址。
對以上這些數據,在函數開始調用時分配動態存儲空間,函數結束時釋放這些空間。
在C語言中,每個變數和函數有兩個屬性:數據類型和數據的存儲類別。
auto變數
函數中的局部變數,如不專門聲明為static存儲類別,都是動態地分配存儲空間的,數據存儲在動態存儲區中。
函數中的形參和在函數中定義的變數(包括在復合語句中定義的變數),都屬此類,在調用該函數時系統會給它們分配存儲空間,在函數調用結束時就自動釋放這些存儲空間。這類局部變數稱為自動變數。自動變數用關鍵字auto作存儲類別的聲明。例如:int f(int a){ /* 定義f函數,a為參數 */ auto int b,c=3; /*定義b,c自動變數*/ /* …… */}
a是形參,b,c是自動變數,對c賦初值3。執行完f函數後,自動釋放a,b,c所佔的存儲單元。
關鍵字auto可以省略,auto不寫則隱含定為「自動存儲類別」,屬於動態存儲方式。
用static聲明局部變數
有時希望函數中的局部變數的值在函數調用結束後不消失而保留原值,這時就應該指定局部變數為「靜態局部變數」,用關鍵字static進行聲明。
【例8-15】考察靜態局部變數的值。
#include<stdio.h>intf(inta){autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);}intmain(void){inta=2,i;for(i=0;i<3;i++)printf("%d ",f(a));return0;}
對靜態局部變數的說明:
靜態局部變數屬於靜態存儲類別,在靜態存儲區內分配存儲單元。在程序整個運行期間都不釋放。而自動變數(即動態局部變數)屬於動態存儲類別,占動態存儲空間,函數調用結束後即釋放。
靜態局部變數在編譯時賦初值,即只賦初值一次;而對自動變數賦初值是在函數調用時進行,每調用一次函數重新給一次初值,相當於執行一次賦值語句。
如果在定義局部變數時不賦初值的話,則對靜態局部變數來說,編譯時自動賦初值0(對數值型變數)或空字元(對字元變數)。而對自動變數來說,如果不賦初值則它的值是一個不確定的值。
【例8-16】列印1到5的階乘值。
#include<stdio.h>intfac(intn){staticintf=1;f=f*n;returnf;}intmain(void){inti;for(i=1;i<=5;i++)printf("%d!=%d ",i,fac(i));return0;}
register變數
為了提高效率,C語言允許將局部變數得值放在CPU中的寄存器中,這種變數叫「寄存器變數」,用關鍵字register作聲明。
【例8-17】使用寄存器變數。
#include<stdio.h>intfac(intn){registerinti,f=1;for(i=1;i<=n;i++)f=f*i;returnf;}intmain(void){inti;for(i=0;i<=5;i++)printf("%d!=%d ",i,fac(i));return0;}
對寄存器變數的幾點說明:
只有局部自動變數和形式參數可以作為寄存器變數;
一個計算機系統中的寄存器數目有限,不能定義任意多個寄存器變數;
局部靜態變數不能定義為寄存器變數。
用extern聲明外部變數
外部變數(即全局變數)是在函數的外部定義的,它的作用域為從變數定義處開始,到本程序文件的末尾。如果外部變數不在文件的開頭定義,其有效的作用范圍只限於定義處到文件終了。如果在定義點之前的函數想引用該外部變數,則應該在引用之前用關鍵字extern對該變數作「外部變數聲明」。表示該變數是一個已經定義的外部變數。有了此聲明,就可以從「聲明」處起,合法地使用該外部變數。
『叄』 C語言中函數是如何存儲的
1. 代碼本身是存儲在內存的代碼段中的,而函數沒有說存儲的概念,函數調用時是通過棧來實現的。
2.在函數體內聲明的變數在默認情況下都是auto存儲類型
在代碼塊之間傳遞信息的一種方法就是使用外部變數。當一個變數在函數的外部被聲明時,安的存儲空間是永久分配的,安人存儲類型是extren.外部變數的聲明看上去和函數或代碼塊內部所聲明的變數一樣。外部變數對於它之後的所有函數都有效。在代碼塊或函數後,外部變數仍然存在。
3.static的基本用途是允許一個局部變數在重新進入代碼塊時能夠保持原來的值。這和自動變數形成了鮮明的對比,自動變數在代碼塊時會被銷毀,再次進入這個代碼塊時,它必須重新進行初始化。
4.egister存儲類型告訴編譯器相關的變數應該改量存儲在高速度的寄存器中。使用register存儲類型的目的一般是為了提高執行速度,但是,register聲明只是向編譯器所提出的「建議」,並非強制要求。