C 程序的外部變量與函數
武漢市東湖中學(xué)
朱海清 孟學(xué)楨
本文討論了C程序的外部變量和函數的一些性質(zhì),結合實(shí)際的編程,給出了使用外部變量和函數的方法。
關(guān)鍵字:C程序,外部變量,函數
C程序由一組對象組成,這些對象包括程序中所使用的變量和實(shí)現特定功能的函數。變量可以分為函數內部定義、使用的變量和函數外部定義的變量,通常情況下,把函數內部定義、使用的變量稱(chēng)為內部變量或局部變量,而將在函數外部定義的、供許多函數所使用的變量稱(chēng)為外部變量,一般情況下,也可以稱(chēng)為全局變量。
由于C語(yǔ)言不允許在一個(gè)函數中定義其他函數,因此函數本身是外部的。一般情況下,也可以說(shuō)函數是全局函數。
在缺省情況下,外部變量與函數具有如下性質(zhì):所有通過(guò)名字對外部變量與函數的引用(即使這種引用來(lái)自獨立編譯的函數)都是引用的同一對象(標準中把這一性質(zhì)稱(chēng)為外部連接)。
由于外部變量是可以全局訪(fǎng)問(wèn)的,這就為在函數之間交換數據提供了一種可以替代函數變元欲返回值的方法。任何函數都可以用名字來(lái)訪(fǎng)問(wèn)外部變量,只要這個(gè)名字已在某個(gè)地方做了說(shuō)明或定義。
如果要在函數之間共享大量的變量,那么使用外部變量要比使用一個(gè)長(cháng)長(cháng)的變元表更方便、有效。然而,也可能導致程序在各個(gè)函數之間產(chǎn)生太多的數據聯(lián)系。
外部變量的用途還表現在它們比內部變量有更大的作用域和更長(cháng)的生存期。內部自動(dòng)變量只能在函數內部使用,當其所在函數被調用時(shí)開(kāi)始存在,當函數退出時(shí)消失。而外部變量是永久存在的,他們的值在從一次函數調用到下一次函數調用之間保持不變。因此,如果兩個(gè)函數必須共享某些數據,而這兩個(gè)函數都互不調用對方,那么最為方便的是,把這些共享數據作為外部變量,而不是作為變元來(lái)傳遞。
1、外部變量的定義和使用
根據C語(yǔ)言標準,在程序的所有源文件中,外部變量只能被定義一次,否則會(huì )導致重復定義的編譯錯誤。
1.1 外部變量的定義與聲明
變量聲明用于通報變量的性質(zhì)(主要是變量的類(lèi)型),而變量定義則除此之外還引起存儲分配。如果在函數的外部包含如下說(shuō)明:
int VarDesc;char Array[MAXVAL];那么這兩個(gè)說(shuō)明定義了外部變量VarDesc與Array,并為之分配存儲單元,同時(shí)也用作供源文件其余部分使用的說(shuō)明。另一方面,如下兩行:
extern int VarDesc;extern char Array[];為源文件剩余部分聲明了VarDesc是一個(gè)int 類(lèi)型的外部變量,Array是一個(gè)char數組類(lèi)型的外部變量(數組大小在其他地方確定),但這兩個(gè)聲明并沒(méi)有建立變量或為它們分配存儲單元,其中關(guān)鍵字extern表明該外部變量在其他地方被定義。
1.2 外部變量的使用方式
如果外部變量被不同的函數所引用,并且這些函數沒(méi)有集中在一個(gè)源文件中,而是分布在不同的源文件中,那么函數在引用這些外部變量時(shí),必須采取先聲明再使用的方式,否則,在編譯時(shí)會(huì )導致重復定義的編譯錯誤。
若在多個(gè)文件的多個(gè)函數中引用外部變量,就需要在這些函數中重復聲明外部變量。這種方式可以解決編譯問(wèn)題,但是代碼不夠簡(jiǎn)潔。因此,在實(shí)際的編程中,大都采取了將外部變量統一定義在一個(gè)C源文件中,這個(gè)C源文件一般被稱(chēng)為global.c,然后在對應的頭文件中,一般為global.h,聲明外部變量,最后在需要引用外部變量的源文件中使用#include "global.h"的方式,函數就可以引用所有的外部變量。因此,一般情況下,global.c內容為:
#include "global.h" /* for example, define two vars */int VarDesc;char Array[MAXVAL];/* other external var define */在對應的global.h頭文件的內容則為:
#ifndef _GLOBAL_H /* please insure _GLOBAL_H unique */#define _GLOBAL_H /* avoid quotation iterativly */#ifdef __cplusplusextern "C" {#endif /*__cplusplus *//* for example, declare two vars */extern int VarDesc;extern char Array[];/* other external vars declaration */#ifdef __cplusplus}#endif /* __cplusplus */#endif /* _GLOBAL_H */ 此外,在實(shí)際的編程中,這兩個(gè)文件頭部還應當有公司copyright聲明、文件功能說(shuō)明、版本說(shuō)明、創(chuàng )建、修改歷史等。2、函數的定義和使用
根據C語(yǔ)言標準,函數只能被定義一次,而且在函數中,不能再定義函數,因此函數本身是外部的。
2.1 函數的定義與聲明
定義函數是給出函數體的函數描述。一個(gè)函數只有在聲明之后才能被引用。函數聲明中,需給出函數名、返回類(lèi)型、參數列表等。
函數的作用域從其聲明處開(kāi)始一直到其所在的被編譯的文件的末尾,如果一個(gè)函數在定義之前就要使用到,或者這個(gè)函數定義在與所要使用它的源文件不相同的源文件中,那么就需要在使用該函數前,使用關(guān)鍵字extern聲明該函數,但由于函數默認是external的,因此函數聲明前的extern可以省略,這也是標準庫函數的頭文件中,函數聲明前沒(méi)有extern的原因,但在實(shí)際的編程中,一般不推薦這樣做,應當在函數聲明前加上extern。
2.2 函數的組織和使用
如果某個(gè)函數需要引用另一個(gè)函數,則需要在引用該函數前聲明被引用的函數,否則可能會(huì )導致函數未定義錯誤。
為了避免被引用函數的重復聲明和方便函數的引用,在實(shí)際的編程之中,采用在對應的頭文件中,統一聲明函數的方式。需要引用某一個(gè)函數時(shí),只需要在該函數的定義源文件中包含被引用函數的頭文件即可。
在實(shí)際的編程中,在頭文件中聲明函數,即聲明函數原型,在對應的C源文件中,定義函數及其實(shí)現代碼。 因此,函數說(shuō)明的頭文件內容和格式為:
#ifndef _FUNCNAME_H /* please insure _ FUNCNAME _H unique */#define _ FUNCNAME _H /* avoid quotation iterativly */#ifdef __cplusplusextern "C" {#endif /*__cplusplus *//* for example, declare functions */extern int func (int, int, int);/* of course, maybe declare functions like below * int func (int, int, int);*//* other functions declaration */#ifdef __cplusplus}#endif /* __cplusplus */#endif /* _ FUNCNAME _H */而在對應的C源文件內容為:#include " funcname.h"/* for example, define two vars */int func (int a, int b, int c){ // functions body}/* other functions define */在實(shí)際的函數頭文件和定義文件中還應當包含相應的頭文件等,以及公司copyright聲明、文件功能說(shuō)明、版本說(shuō)明、創(chuàng )建、修改歷史等。對于具體的函數,還應當有函數說(shuō)明、輸入參數說(shuō)明、返回說(shuō)明、例外等。3、靜態(tài)外部變量和函數
如果某外部變量和函數僅供它們各自所在的源文件中的函數使用,而不能被其他函數訪(fǎng)問(wèn),那么就必須使用static關(guān)鍵字定義外部變量和函數。static說(shuō)明適用于外部變量與函數,用于把這些對象的作用域限定為被編譯源文件的剩余部分。通過(guò)外部static對象,可以把一些外部變量和函數隱藏在某個(gè)源文件中,使得這些外部變量和函數僅僅可以被該源文件使用和共享,但不能被該源文件之外的函數所引用。
另外,static說(shuō)明也可以用于說(shuō)明內部變量。內部靜態(tài)變量就像自動(dòng)變量一樣局部于某一個(gè)特定函數,只能在該函數中使用,但與自動(dòng)變量不同的是,不管其所作函數是否被調用,它都是一直存在的,而不像自動(dòng)變量那樣,隨著(zhù)所在函數的調用與退出而存在與消失。換而言之,內部靜態(tài)變量是一種只能在某一特定函數中使用的但一直占據存儲空間的變量。
一般情況下,為保證靜態(tài)外部變量和函數能夠被本源文件的函數所引用,需要在該源文件的所有函數之前定義靜態(tài)外部變量和函數。 那么,該C源文件的內容為:
#include “funcname.h” /* for example, define one static external var and one static function */static int VarName = 0;static int function (int a){ // function body}/* other static vars and functions *//* for example, define one function */char func (char*, char){ VarName = 5; function (VarName); // other function body}/* other functions define */參考文獻:聯(lián)系客服