变量的生存期
我們在前面的課程中曾經(jīng)提到,系統(tǒng)在執(zhí)行某個函數(shù)時,會給這個函數(shù)分 配一塊新的內(nèi)存。在這塊新內(nèi)存中存放這個函數(shù)的局部變量和形參變量。
下面我們先來了解一下一個C程序在執(zhí)行時內(nèi)豐的分配狀態(tài)。如果學(xué)過匯 編的話就應(yīng)該知道,系統(tǒng)一開機(jī)后,內(nèi)存被分為兩大塊。一塊是系統(tǒng)區(qū),存放 操作系統(tǒng)等內(nèi)容,另一塊是用戶區(qū),用來存放被執(zhí)行的用戶程序。我們主要研 究一下在用戶區(qū)的內(nèi)存分配情況。
一個C程序在運(yùn)行時,用戶區(qū)被分為三大塊:第一塊是程序區(qū),用來存放 C程序運(yùn)行代碼。第二塊是靜態(tài)存儲區(qū),用來存放變量,在這個區(qū)域中存儲的 變量被稱作靜態(tài)變量,如全局變量。第三塊是動態(tài)存儲區(qū),也用來存放變量 以及進(jìn)行函數(shù)調(diào)用時的現(xiàn)場信息和函數(shù)返回地址等,在這個區(qū)域存儲的變量 我們稱之為動態(tài)變量,如形參變量、函數(shù)體內(nèi)部定義的局部變量。
在C語言中,每一個變量都有兩個屬性:數(shù)據(jù)類型和數(shù)據(jù)的存儲類別。數(shù) 據(jù)類型是我們前面講過的整型、實(shí)型等。而存儲類別主要指一個變量在內(nèi)存 中的存儲區(qū)域,分為兩大類:靜態(tài)存儲和動態(tài)存儲。
可是在C的源程序中,我們怎么來規(guī)定變量的存儲類別呢?
一、靜態(tài)存儲變量
凡是用關(guān)鍵字static定義的變量全部被稱為靜態(tài)變量。所有的靜態(tài)變量全 部存儲在靜態(tài)存儲區(qū),在程序的運(yùn)行期間一直存在。
按靜態(tài)變量定義位置的不同,又分為全局靜態(tài)變量和局部靜態(tài)變量。它們 有一些小小的區(qū)別。
全局靜態(tài)變量實(shí)際上就是全局變量,一個程序中的全局變量全部存儲在靜 態(tài)存儲區(qū)中。
局部靜態(tài)變量指的是在某個函數(shù)中用關(guān)鍵字static定義的變量,這種變量的作用范圍只在定義它的函數(shù)起作用,但是它存儲在靜態(tài)存儲區(qū)。我們知道, 一個函數(shù)在返回時要將其所占有的內(nèi)存交還系統(tǒng)。但如果這個函數(shù)中定義有靜 態(tài)變量,函數(shù)在返回時這個靜態(tài)變量不會被釋放,仍然保存它的值。如果再次 調(diào)用這個函數(shù)時,我們就可以直接使用這個保存下來的值.
看下面的例子:
int f()
{static y=0;
y++;
return(y);
}
main()
{int i;
for (i=0;i<5;i++)
printf("%3d",f()); }
運(yùn)行結(jié)果:
1 2 3 4 5_
我們在f函數(shù)的內(nèi)部定義了一個靜態(tài)變量,對這個函數(shù)調(diào)用了五次。雖然 在函數(shù)內(nèi)部有一條初始化語句,但由于y是靜態(tài)變量,所以只在對f函數(shù)進(jìn)行第 一次調(diào)用時才對y進(jìn)行初始化,其它次的調(diào)用就直接使用y變量而不再進(jìn)行初始 化了。
說明:
1、局部的靜態(tài)變量如果不對其進(jìn)行初始化,那么系統(tǒng)自動對其賦值0。
2、雖然局部的靜態(tài)變量在函數(shù)返回后依然存在,但由于它是局部變量,所以 其它函數(shù)仍然不能對它進(jìn)行引用。
3、C語言規(guī)定,只有存儲在靜態(tài)存儲區(qū)中的變量才能對其進(jìn)行初始化,實(shí)際上就是我們前面提到過的:只有對全局變量和用static定義的變量才能進(jìn)行初 始化。
4、對靜態(tài)變量的初始化是在編譯階段完成的,即在程序運(yùn)行前就已經(jīng)初始化 完畢了。
二、動態(tài)存儲變量
動態(tài)存儲變量是存儲在動態(tài)存儲區(qū)的,這種變量只在定義它們的時候才創(chuàng) 建,在定義它們的函數(shù)返回時系統(tǒng)回收變量所占內(nèi)存。對這些變量的創(chuàng)建和回 收是由系統(tǒng)自動完成的,所以也叫自動變量(用關(guān)鍵字auto定義)。最典型的 例子就是函數(shù)中定義的局部變量。
一般情況下,關(guān)鍵字auto可以省略,上面這行可以寫成 int b,c=4; 它們是 等價(jià)的。這樣看來,形參變量a也是自動變量。在我們在前面的學(xué)習(xí)中,見到 的大部分是自動變量。
一般情況下所有的變量是存放在內(nèi)存中的,我們知道,計(jì)算機(jī)是一個多級 緩存系統(tǒng)。程序在運(yùn)行時,只有需要計(jì)算的變量才從內(nèi)存中取到運(yùn)算器。如果 有一個變量在某一段時間內(nèi)重復(fù)使用的次數(shù)很多,如循環(huán)變量。那么,這種從 內(nèi)存取數(shù)的過程將花費(fèi)大量的時間。所以對這種重復(fù)使用的變量,C語言允許 它存放在寄存器中,以提高程序的運(yùn)行效率。這種變量被稱作“寄存器變量” ,用關(guān)鍵字register定義。
因?yàn)橛?jì)算機(jī)系統(tǒng)中寄存器的數(shù)目是非常有限的,所以決定了在C程序中寄 存器變量的數(shù)目有一定的限制,而且只有動態(tài)變量才能作為“寄存器變量”。另外在一些C語言系統(tǒng)中(如Turbo C和MS C),“寄存器變量”實(shí)際上是被 當(dāng)作自動變量來處理的,仍然將這種變量存放在內(nèi)存中。所以對這種變量,我 們只要了解一下就行。
三、全局變量的類別
到這里我們已經(jīng)學(xué)習(xí)了三種存儲類別 static、auto、register。前面提到,全局變量是靜態(tài)變量。但是,一個C程序可能是由多個源文件組成的。根據(jù)全 局變量是否能被其它源程序使用,又將全局變量分為外部的和內(nèi)部的。
1、如果想允許其它源文件訪問本文件中的全局變量,在其它源文件中通 過使用關(guān)鍵字extern來定義全局變量。
對全局變量的這種規(guī)定,使得多人分工合作來完成一個任務(wù)變得容易。 不用擔(dān)心自己的變量名與別人的重名。
經(jīng)過這一節(jié)的學(xué)習(xí),我們知道了變量有四種具體的存儲類別: (static,auto.register,extern)。
原文來自:http://www.nttvu.edu.cn/sec/kcjx/c/zs/..%5Czs%5Czs79.htm
總結(jié)
- 上一篇: TWRP-recovery中文界面安装方
- 下一篇: 溢出和剪裁,可见性