7.7 變量的存儲(chǔ)類(lèi)別、作用域及生存期
1.變量的存儲(chǔ)類(lèi)別
在C語(yǔ)言中,有兩類(lèi)存儲(chǔ)類(lèi)別:自動(dòng)類(lèi)別及靜態(tài)類(lèi)別。
有4個(gè)與兩種存儲(chǔ)類(lèi)別有關(guān)的說(shuō)明符:auto(自動(dòng))、register(寄存器)、static(靜態(tài))和extern(外部),這些說(shuō)明符一般與類(lèi)型說(shuō)明一起出現(xiàn),一般放在類(lèi)型名的左邊,例如:
auto long I,j;
也可寫(xiě)成:
long auto I,j;
(1)自動(dòng)變量:自動(dòng)變量是C程序中使用最多的一種變量,這種變量的建立和撤消都是在系統(tǒng)中自動(dòng)進(jìn)行的。
格式:[auto]數(shù)據(jù)類(lèi)型 變量名[=初始化表達(dá)式],…;
上面的說(shuō)明格式中,方括號(hào)中是可省略的部分,auto為自動(dòng)類(lèi)別標(biāo)識(shí)符,若省略auto,系統(tǒng)缺省的存儲(chǔ)類(lèi)別也為自動(dòng)類(lèi)別。
注意:函數(shù)的形參也為自動(dòng)類(lèi)別,在定義時(shí)不必加存儲(chǔ)類(lèi)別標(biāo)識(shí)符。
(2)寄存器變量:寄存器變量與自動(dòng)變量的性質(zhì)相同,其區(qū)別只在于存儲(chǔ)的位置不同,寄存器變量存儲(chǔ)在CPU的寄存器中,而自動(dòng)變量存儲(chǔ)在內(nèi)存中的動(dòng)態(tài)存儲(chǔ)區(qū),寄存器變量的存取速度要快些。
格式:register數(shù)據(jù)類(lèi)型,變量名[=初始化表達(dá)式],…;
上面的說(shuō)明格式中,register為寄存器變量的存儲(chǔ)類(lèi)別標(biāo)識(shí)符。
說(shuō)明:
①CPU中寄存器的數(shù)目是有限的,因此只能把少數(shù)的變量說(shuō)明為寄存器變量;
②寄存器變量是存放在寄存器中的,而不是存放于內(nèi)存中,所以,寄存器變量無(wú)地址;
③寄存器變量的說(shuō)明應(yīng)盡量放在靠近要使用的地方,用完后盡快釋放,這樣可提高使用效率。
(3)靜態(tài)變量:靜態(tài)類(lèi)別變量的存儲(chǔ)空間在程序的整個(gè)運(yùn)行期間是固定的。
格式:static數(shù)據(jù)類(lèi)型 變量名[=初始化表達(dá)式],…;
在上面的說(shuō)明格式中,static為靜態(tài)變量的存儲(chǔ)類(lèi)別標(biāo)識(shí)符。
靜態(tài)變量的初始化在編譯時(shí)進(jìn)行,定義時(shí)可用常量或表達(dá)式進(jìn)行顯式初始化。對(duì)于沒(méi)有初始化的靜態(tài)變量,自動(dòng)初始化為0(整型)或0.0(實(shí)型)。
注意:靜態(tài)變量具有可繼承性,這與自動(dòng)變量有所不同。
(4)外部變量:使用extern可使外部變量使用范圍擴(kuò)充到需要使用它的函數(shù)。外部變量可作顯式的初始化,若不作初始化,系統(tǒng)將自動(dòng)地初始化為0或0.0。
格式:[extern]數(shù)據(jù)類(lèi)型,變量名[=初始化表達(dá)式],…;
上面的說(shuō)明格式中,extern使外部變量的作用范圍擴(kuò)大到其他源程序文件中。
注意:局部變量既可以說(shuō)明為自動(dòng)類(lèi)別,也可以說(shuō)明為靜態(tài)類(lèi)別;全局變量只能說(shuō)明為靜態(tài)類(lèi)別。
2.變量的作用域及生存期
在C語(yǔ)言中,變量必須先說(shuō)明后使用,在程序中一個(gè)已定義的變量的使用范圍就是此變量的作用域。經(jīng)過(guò)賦值的變量在程序運(yùn)行期間能保持其值的時(shí)間范圍為該變量的生存期。
(1)局部變量的使用域及生存期
①自動(dòng)變量的使用域及生存期
自動(dòng)變量的存儲(chǔ)單元被分配在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū),每當(dāng)進(jìn)函數(shù)體(或復(fù)合語(yǔ)句)時(shí),系統(tǒng)自動(dòng)為自動(dòng)變量分配存儲(chǔ)單元,退出時(shí)自動(dòng)釋放這些存儲(chǔ)單元。自動(dòng)變量的作用域?yàn)閺亩x的位置起,到函數(shù)體(或復(fù)合語(yǔ)句)結(jié)束為止。
自動(dòng)變量在進(jìn)入到定義它們的函數(shù)體(或復(fù)合語(yǔ)句)時(shí)生成,在退出所在的函數(shù)體(或復(fù)合語(yǔ)句)時(shí)消失,這就是自動(dòng)變量的生存期。
使用自動(dòng)變量的優(yōu)點(diǎn)是使各函數(shù)之間造成信息分隔,不同函數(shù)中使用同名變量時(shí)不會(huì)相互影響。
②寄存器變量的使用域及生存期
寄存器變量的使用域及生存期與自動(dòng)變量相同。
③靜態(tài)存儲(chǔ)類(lèi)別的局部變量
在函數(shù)體(或復(fù)合語(yǔ)句)內(nèi)部,用static說(shuō)明的變量靜態(tài)存儲(chǔ)類(lèi)別的局部變量,這種變量的作用域與自動(dòng)(或寄存器)變量的作用域相同,但是生存期有所不同。
在整個(gè)程序運(yùn)行期間,靜態(tài)局部變量在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)中占據(jù)著永久的存儲(chǔ)單元,甚至在退出函數(shù)后下次再進(jìn)入函數(shù)時(shí),靜態(tài)局部變量仍使用原來(lái)的存儲(chǔ)單元。由于不釋放存儲(chǔ)單元,所以這些存儲(chǔ)單元中的值將會(huì)被保留下來(lái)。靜態(tài)局部變量的生存期將一直延長(zhǎng)到程序運(yùn)行結(jié)束。
靜態(tài)局部變量適合于在函數(shù)調(diào)用之間必須保留局部變量值的獨(dú)立變量。
(2)全局變量的作用域及生存期
全局變量的作用域?yàn)閺淖兞慷x的位置開(kāi)始,到整個(gè)源程序文件結(jié)束為止。生存期為整個(gè)程序的運(yùn)行期間。
注意:全局變量在整個(gè)程序運(yùn)行期間都占用內(nèi)存空間。全局變量必須在函數(shù)以外定義,因而降低了函數(shù)的通用性,影響函數(shù)的獨(dú)立性。使用全局變量時(shí),當(dāng)全局變量的值意外改變時(shí),會(huì)引起副作用,這種錯(cuò)誤一般難以查找。
①在同一編譯單位內(nèi)用extern標(biāo)識(shí)符來(lái)擴(kuò)展全局變量的作用域
當(dāng)全局變量定義后,在引用函數(shù)前,應(yīng)在引用它的函數(shù)中用extern對(duì)此全局變量進(jìn)行說(shuō)明,以便使編輯程序確定此外部變量已被定義,不必再為它分配存儲(chǔ)單元,此時(shí)的作用域從extern說(shuō)明開(kāi)始,到此函數(shù)結(jié)束。
注意:全局變量的定義只能出現(xiàn)一次,這時(shí)不可使用extern標(biāo)識(shí)符。如果多次引用全局變量,這時(shí)必須用extern標(biāo)識(shí)符。
②在不同編譯單位內(nèi)用extern標(biāo)識(shí)符來(lái)擴(kuò)展全局變量的作用域
C語(yǔ)言中的不同函數(shù)可以存放在不同的源程序文件中,每個(gè)源程序文件可以單獨(dú)進(jìn)行編譯,進(jìn)行語(yǔ)法檢查,再生成目標(biāo)文件,最后用系統(tǒng)提供的連接程序把多個(gè)目標(biāo)文件連接成一個(gè)可執(zhí)行程序。
當(dāng)程序由多個(gè)源程序文件組成時(shí),若每個(gè)文件中都要引用同一個(gè)全局變量,這時(shí)如在每個(gè)源程序文件中都定義一個(gè)所需的同名全局變量,將在連接時(shí)產(chǎn)生重復(fù)定義錯(cuò)誤。解決的辦法是在其中一個(gè)源程序文件中定義所有全局變量,而在其他用到全局變量的源程序文件中用extern對(duì)這些變量進(jìn)行說(shuō)明,以表明它們已在其他編譯單元中被定義。
③靜態(tài)全局變量
當(dāng)用static標(biāo)識(shí)符說(shuō)明全局變量時(shí),全局變量為靜態(tài)全局變量。靜態(tài)全局變量只能在定義它的源程序文件中使用,不能被其他源程序文件使用。