使用 static 修飾的變數或函式的作用域僅限於當前模組,對其他模組隱藏,利用這一特性可以在不同的檔案中定義同名的變數或函式,而不必擔心命名衝突。

static 除了可以修飾全域性變數,還可以修飾區域性變數,被 static 修飾的變數統稱為靜態變數(Static Variable)。

不管是全域性變數還是區域性變數,只要被 static 修飾,都會儲存在全域性資料區(全域性變數本來就儲存在全域性資料區,即使不加 static)。

全域性資料區的資料在程式啟動時就被初始化,一直到程式執行結束才會被作業系統回收記憶體;對於函式中的靜態區域性變數,即使函式呼叫結束,記憶體也不會銷燬

注意:全域性資料區的變數只能被初始化(定義)一次,以後只能改變它的值,不能再被初始化,即使有這樣的語句,也無效。

我們在 func() 中定義了一個靜態區域性變數 n,它儲存在全域性資料區,func() 函式執行結束不會被銷燬,下次呼叫繼續有效。全域性資料區的變數只能初始化一次,第一次呼叫 func() 時已經對 n 進行了初始化,所以再次呼叫時就不會重複初始化了。

靜態區域性變數雖然儲存在全域性資料區,但是它的作用域僅限於函式內部!!!!

例子:

//作者:王磊
#include <stdio.h>
int func(){
    // 也可以不賦初值 0,靜態資料區的變數預設初始化為 0
    static int n = 2;
    n++;
    printf("Function is called %d times.\n", n);
    return n;
}
int main(){
    int i, n = 0;
    for(i = 1; i<=5; i++){
        func();
    }
    printf("n = %d\n", n);
    //全域性資料區的資料在程式啟動時就被初始化,
    //一直到程式執行結束才會被作業系統回收記憶體;
    //對於函式中的靜態區域性變數,即使函式呼叫結束,
    //記憶體也不會銷燬。
    func();        //此時螢幕輸出為8
    return 0;
}

總結起來,static 變數主要有兩個作用:

1) 隱藏

程式有多個模組時,將全域性變數或函式的作用範圍限制在當前模組,對其他模組隱藏。

2) 保持變數內容的持久化

將區域性變數儲存到全域性資料區,使它不會隨著函式呼叫結束而被銷燬。