c語言中static 用法和extern

2021-06-27 20:20:48 字數 2879 閱讀 2766

static在c裡面可以用來修飾變數,也可以用來修飾函式。

先看用來修飾變數的時候。變數在c裡面可分為存在全域性資料區、棧和堆裡。其實我們平時所說的堆疊是棧而不是堆,不要弄混。

int a ;

int main()

a是全域性變數,b是棧變數,c是堆變數。

static對全域性變數的修飾,可以認為是限制了只能是本檔案引用此變數。有的程式是由好多.c檔案構成。彼此可以互相引用變數,但加入static修飾之後,只能被本檔案中函式引用此變數。

static對棧變數的修飾,可以認為棧變數的生命週期延長到程式執行結束時。一般來說,棧變數的生命週期由os管理,在退棧的過程中,棧變數的生命也就結束了。但加入static修飾之後,變數已經不再儲存在棧中,而是和全域性變數一起儲存。同時,離開定義它的函式後不能使用,但如再次呼叫定義它的函式時,它又可繼續使用, 而且儲存了前次被呼叫後留下的值。

static對函式的修飾與對全域性變數的修飾相似,只能被本檔案中的函式呼叫,而不能被同一程式其它檔案中的函式呼叫。

檔案a.c

static 

int 

i; //只在a檔案中用

int 

j; //在工程裡用

static 

void 

init() 

//只在a檔案中用

void 

callme() 

//在工程中用

上面的全域性i變數和init()函式只能用在a.c檔案中,全域性變數sum的作用域只在callme裡。變數j和函式callme()的全侷限擴充到整個工程檔案。所以可以在下面的b.c中用extern關鍵字呼叫。extern告訴編譯器這個變數或者函式在其他檔案裡已經被定義了。

檔案b.c

extern 

int 

j; //呼叫a檔案裡的

extern 

void 

callme(); 

//呼叫a檔案裡的

int 

main()

extern的另外用法是當c和c++混合程式設計時如果c++呼叫的是c原始檔定義的函式或者變數,那麼要加extern來告訴編譯器用c方式命名函式:

檔案a.cpp呼叫a.c裡面的變數i和函式callme()

extern 

"c" 

//在c++檔案裡呼叫c檔案中的變數

int 

main()

二 static法則:

a、若全域性變數僅在單個c檔案中訪問,則可以將這個變數修改為靜態全域性變數,以降低模組間的耦合度;

b、若全域性變數僅由單個函式訪問,則可以將這個變數改為該函式的靜態區域性變數,以降低模組間的耦合度;

c、設計和使用訪問動態全域性變數、靜態全域性變數、靜態區域性變數的函式時,需要考慮重入問題;

全域性變數有外部、靜態兩種儲存方式。

(1)全域性變數一般用外部儲存方式儲存,用保留字extern加以定義。此時,變數的作用域是構成整個程式的所有程式檔案,也就是定義的外部變數可供其它程式檔案使用。

使用這樣的全域性變數一定要非常慎重,一旦產生錯誤,將波及整個程式。

(2)如果希望全域性變數僅限於本程式檔案使用,而其它程式檔案中不能引用,這時必須將其儲存方式定義為靜態儲存方式,用保留字static加以定義。此時稱為靜態外部變數。

例如,在上例檔案filel.c中,如果作這樣的定義:

static int a:

則變數a的作用域被縮小至本程式檔案filel.c,檔案file2.c中不能引用。

值得注意的是對全域性變數加static,定義為靜態儲存方式,並不意味著是靜態儲存;而不加static,是動態儲存。兩種形式的全域性變數(外部變數)都是靜態儲存方式,都是編譯時分配儲存空間,但作用域不同。使用靜態外部變數,有利於隔離錯誤,有利於模組化程式設計。

(3)全域性變數的預設儲存方式是外部儲存方式。

前面章節中的程式沒有見到變數的儲存類別定義,實際上採用變數的預設儲存方式。對區域性變數採用auto方式,對全域性變數採用extern方式。這也是至今為止,我們在程式中沒有見到auto、extern等的原因。

至此,我們對變數的儲存類別及資料型別進行了全面討論,在此作個小結。

1.變數定義的一般形式

儲存類別資料型別變數表;

2.變數定義的作用

①規定了變數的取值範圍。

②規定了變數進行的執行操作。

③規定了變數的作用域。

④規定了變數的儲存方式。

⑤規定了變數占用的儲存空間。

3.區域性變數和全域性變數

從作用域角度將變數分為區域性變數和全域性變數。它們採取的儲存類別如下:

區域性變數:

①自動變數,即動態區域性變數(離開函式,值就消失)。

②靜態區域性變數(離開函式,值仍保留)。

③暫存器變數(離開函式,值就消失)。

④形式引數可以定義為自動變數或暫存器變數。

全域性變數:

①靜態外部變數(只限本程式檔案使用)。

②外部變數(即非靜態的外部變數,允許其它程式檔案引用)。

4.動態儲存和靜態儲存

從變數存在時間可將變數儲存分為動態儲存和靜態儲存。靜態儲存是在整個程式執行時都存在,而動態儲存則是在呼叫函式時臨時分配儲存單元。

動態儲存:

①自動變數(函式內有效)。

②暫存器變數(函式內有效)。

③形式引數。

靜態儲存:

①靜態區域性變數(函式內有效)。

②靜態外部變數(本程式檔案內有效)。

③外部變數(整個程式可引用)。

5.靜態儲存區和動態儲存區

從變數值存放的位置可將變數儲存區分為靜態儲存區和動態儲存區:

記憶體中靜態儲存區:

①靜態區域性變數。

②靜態外部變數。

③外部變數(可被同一程式其它檔案引用)。

記憶體中動態儲存區:自動變數和形式引數。

cpu中的暫存器:暫存器變數。

c語言中static 用法

static在c裡面可以用來修飾變數,也可以用來修飾函式。先看用來修飾變數的時候。變數在c裡面可分為存在全域性資料區 棧和堆裡。其實我們平時所說的堆疊是棧而不是堆,不要弄混。int a int main a是全域性變數,b是棧變數,c是堆變數。static對全域性變數的修飾,可以認為是限制了只能是本...

c語言中static 用法

static在c裡面可以用來修飾變數,也可以用來修飾函式。先看用來修飾變數的時候。變數在c裡面可分為存在全域性資料區 棧和堆裡。其實我們平時所說的堆疊是棧而不是堆,不要弄混。int a int main a是全域性變數,b是棧變數,c是堆變數。static對全域性變數的修飾,可以認為是限制了只能是本...

c語言中static 用法

static在c裡面可以用來修飾變數,也可以用來修飾函式。先看用來修飾變數的時候。變數在c裡面可分為存在全域性資料區 棧和堆裡。其實我們平時所說的堆疊是棧而不是堆,不要弄混。int a int main a是全域性變數,b是棧變數,c是堆變數。static對全域性變數的修飾,可以認為是限制了只能是本...