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對全域性變數的修飾,可以認為是限制了只能是本...