王希琴
(包頭財(cái)經(jīng)學(xué)校,內(nèi)蒙古 包頭 014030)
C語(yǔ)言中變量的解析
王希琴
(包頭財(cái)經(jīng)學(xué)校,內(nèi)蒙古 包頭 014030)
通過對(duì)C語(yǔ)言中四種變量的不同方面的介紹,可以讓我們更精確地掌握它并根據(jù)實(shí)際情況選擇相應(yīng)的變量來(lái)應(yīng)用開發(fā)出高質(zhì)量的軟件.
作用域;存儲(chǔ)類型;全局變量;局部變量;靜態(tài)變量;寄存器變量
一直以來(lái),對(duì)于初學(xué)者而言,函數(shù)就是一個(gè)比較難以掌握的問題,尤其是函數(shù)中的變量更是讓初學(xué)者理不出一個(gè)明確的思路,因而不能清晰的去掌握,所以也不敢去輕易地應(yīng)用,浪費(fèi)了c中精華、寶貴的資源.下面做一個(gè)簡(jiǎn)單的總結(jié)和概括,希望能給初學(xué)者一點(diǎn)點(diǎn)的幫助.c的變量的應(yīng)用分為以下幾個(gè)部分:
C程序的標(biāo)識(shí)符作用域有三種:局部、全局、文件.標(biāo)識(shí)符的作用域決定了程序中的哪些語(yǔ)句可以使用它,換句話說,就是標(biāo)識(shí)符在程序其他部分的可見性.通常,標(biāo)識(shí)符的作用域都是通過它在程序中的位置隱式說明的.
1.1 局部作用域.變量的局部作用域,他們都是聲明在函數(shù)或語(yǔ)句塊的內(nèi)部,無(wú)法被其他函數(shù)或語(yǔ)句塊的代碼所訪問.函數(shù)的形式參數(shù)的作用域也是局部的,它們的作用范圍僅限于函數(shù)內(nèi)部所用的語(yǔ)句塊.
上面例子里的兩個(gè)num變量都是局部變量,只在本身函數(shù)里可見.在兩個(gè)函數(shù)出現(xiàn)同名的變量不會(huì)互相干擾.所以上面的兩個(gè)輸出,在主函數(shù)里是5,在add()函數(shù)里輸出是6.
1.2 全局作用域.對(duì)于具有全局作用域的變量,我們可以在程序的任何位置訪問它們.當(dāng)一個(gè)變量是在所有函數(shù)的外部聲明,也就是在程序的開頭聲明,那么這個(gè)變量就是全局變量.
上面的main()和add()里面,并沒有聲明num,在最后輸出的時(shí)候卻要求輸出num,這是由于在程序的開始聲明了num是全局變量,在所有函數(shù)里都可以使用這個(gè)變量.這時(shí)候一個(gè)函數(shù)里改變了變量的值,其他函數(shù)里的值也會(huì)出現(xiàn)影響.上面的例子輸出都是6,因?yàn)樵赼dd()函數(shù)里改變了num的值,由于num是全局變量,就好象它們兩個(gè)函數(shù)共用一個(gè)變量,所以在main()函數(shù)里的num也隨之改變了.
1.3 文件作用域.文件作用域在較大程序中很有作用.文件作用域是指外部標(biāo)識(shí)符僅在聲明它的同一個(gè)轉(zhuǎn)換單元內(nèi)的函數(shù)中可見.所謂轉(zhuǎn)換單元是指定義這些變量和函數(shù)的源代碼文件.static存儲(chǔ)類型修飾符指定了變量具有文件作用域.
上面的程序中變量num和函數(shù)add()在聲明中采用了static存儲(chǔ)類型修飾符,這使得它們具有文件作用域.
前面我們說了,聲明變量時(shí)用如下形式:
它們都沒有存儲(chǔ)類型修飾符,我們?cè)诼暶鲿r(shí)也可以通過存儲(chǔ)類型修飾符來(lái)告訴編譯器將要處理什么類型的變量.存儲(chǔ)類型有以下四種:自動(dòng)(auto)、靜態(tài)(static)、外部(extern)、寄存器(regiser).
2.1 自動(dòng)存儲(chǔ)類型.自動(dòng)存儲(chǔ)類型修飾符指定了一個(gè)局部變量為自動(dòng)的,這意味著,每次執(zhí)行到定義該變量的語(yǔ)句塊時(shí),都將會(huì)為該變量在內(nèi)存中產(chǎn)生一個(gè)新的拷貝,并對(duì)其進(jìn)行初始化.實(shí)際上,如果不特別指明,局部變量的存儲(chǔ)類型就默認(rèn)為自動(dòng)的.
在這個(gè)例子中,不論變量num的聲明是否包含關(guān)鍵字auto,代碼的執(zhí)行效果都是一樣的.函數(shù)的形式參數(shù)存儲(chǔ)類型默認(rèn)也是自動(dòng)的.
2.2 靜態(tài)存儲(chǔ)變量.前面已經(jīng)使用了static關(guān)鍵字,但是對(duì)于局部變量,靜態(tài)存儲(chǔ)類型的意義是不一樣的,這時(shí),它是和自動(dòng)存儲(chǔ)類型相對(duì)而言的.靜態(tài)局部變量的作用域仍然僅局限于聲明它的語(yǔ)句塊中,但是在語(yǔ)句塊執(zhí)行期間,變量將始終保持它的值.而且,初始化值只在語(yǔ)句塊第一次執(zhí)行時(shí)起作用.在隨后的運(yùn)行過程中,變量將保持語(yǔ)句塊上一次執(zhí)行時(shí)的值.看下面兩個(gè)對(duì)應(yīng)的程序:
上面兩個(gè)源文件,只有函add()里的變量聲明有所不同,一個(gè)是自動(dòng)存儲(chǔ)類型,一個(gè)是靜態(tài)存儲(chǔ)類型.對(duì)于1.C文件,輸出結(jié)果為51 51 51;這很好理解,每次初始值都是50,然后加1上來(lái).對(duì)于2.C文件,輸出結(jié)果為51 52 53;這是由于變量是靜態(tài)的,只在第一次初始化了50,以后都是使用上次的結(jié)果值.當(dāng)?shù)谝淮握{(diào)用add()時(shí),初始化為50,然后加1,輸出為51;當(dāng)?shù)诙握{(diào)用時(shí),就不初始化了,這時(shí)num的值為上次的51,然后加1,輸出52;當(dāng)?shù)谌握{(diào)用時(shí),num為52,加1就是53了.經(jīng)過比較就會(huì)發(fā)現(xiàn)它們的不同之處了.靜態(tài)變量在遞歸函數(shù)中經(jīng)常使用到.
2.3 外部存儲(chǔ)類型.外部存儲(chǔ)類型聲明了程序?qū)⒁玫降?、但尚未定義的外部變量.通常,外部存儲(chǔ)類型都是用于聲明在另一個(gè)轉(zhuǎn)換單元中定義的變量.下面舉一個(gè)例子,這個(gè)例子包括兩個(gè)文件.
這兩個(gè)程序是分別編譯的,然后連接成一個(gè)執(zhí)行文件.把上面兩個(gè)文件都編譯好后,再制作一個(gè).prj文件,里面的內(nèi)容是:第一行為1.c;第二行為2.c
可在編輯狀態(tài)下寫成,存盤,取名為1.prj.然后選擇project選項(xiàng),選擇projectname,填入1.prj文件名,按F9后,即可生成1.exe文件.main()函數(shù)中變量num是在另一個(gè)文件中定義的.因此,當(dāng)編譯器編譯1.c時(shí),無(wú)法確定該變量的地址.這時(shí),外部存儲(chǔ)類型聲明告訴編譯器,把所有對(duì)num的引用當(dāng)作暫且無(wú)法確定的引用,等到所有編譯好的目標(biāo)代碼連接成一個(gè)可執(zhí)行程序模塊時(shí),再來(lái)處理對(duì)變量num的引用.
外部變量的聲明既可以在引用它的函數(shù)的內(nèi)部,也可以在外部.如果變量聲明在函數(shù)外部,那么同一轉(zhuǎn)換單元內(nèi)的所有函數(shù)都可以使用這個(gè)外部變量.反之,如果在函數(shù)內(nèi)部,那么只有這一個(gè)函數(shù)可以使用該變量.
前面說了文件作用域的問題,如果在聲明全局變量時(shí),加上static修飾符,那么該變量只在當(dāng)前文件內(nèi)可見,而extern又可以引用其它文件里的變量.所以在一個(gè)大型程序中,每個(gè)程序員只是完成其中的一小塊,為了讓自己的變量不讓其他程序員使用,保持一定的獨(dú)立性,經(jīng)常在全局變量前加static.
2.4 寄存器存儲(chǔ)類型.被聲明為寄存器存儲(chǔ)類型的變量,除了程序無(wú)法得到其地址外,其余都和自動(dòng)變量一樣.
使用寄存器存儲(chǔ)類型的目的是讓程序員指定某個(gè)局部變量存放在計(jì)算機(jī)的某個(gè)硬件寄存器里而不是內(nèi)存中,以提高程序的運(yùn)行速度.不過,這只是反映了程序員的主觀意愿,編譯器可以忽略寄存器存儲(chǔ)類型修飾符.寄存器變量的地址是無(wú)法取得的,因?yàn)榻^大多數(shù)計(jì)算機(jī)的硬件寄存器都不占用內(nèi)存地址.而且,即使編譯器忽略寄存器類型修飾符把變量放在可設(shè)定地址的內(nèi)存中,我們也無(wú)法取地址的限制仍然存在.
要想有效的利用寄存器存儲(chǔ)類型,必須象匯編語(yǔ)言程序員那樣了解處理器的內(nèi)部構(gòu)造,知道可用于存放變量的寄存器的數(shù)量和種類,以及他們是如何工作的.但是,不同計(jì)算機(jī)在這些細(xì)節(jié)上未必是一樣的,因此對(duì)于一個(gè)可移植的程序來(lái)說,寄存器存儲(chǔ)類型的作用不大.特別是現(xiàn)在很多編譯器都能提供很好的優(yōu)化效果,遠(yuǎn)比程序員來(lái)選擇有效的多.不過,寄存器存儲(chǔ)類型還是可以為優(yōu)化器提供重要的參考.
最后,還是總結(jié)一下定義為不同類型的變量的相同和不同之處,以便于更好地運(yùn)用.
TP312
A
1673-260X(2010)02-0045-02
?