用了這么久的C語言,之前對于static關鍵字的用法總是一知半解,今天終于搞清楚了,寫個文章簡單記錄一下。
用static修飾的變量,不管是全局變量還是局部變量,其存儲位置都是靜態存儲區,全局變量作用域是當前文件,局部變量是其定義的函數塊內部。
需要注意的是,用static修飾后的局部變量其生命周期是在整個程序運行期間,而不再是在函數執行完銷毀。
對于全局變量和函數來說,有沒有static修飾影響著其鏈接屬性,如果都不加static修飾,那么其鏈接屬性就是外部鏈接,什么意思呢,舉個例子。假設a.c和b.c是一起編譯的兩個文件,它們在編譯完成后,其各自的目標文件a.o和b.o就會被鏈接在一起形成一個可執行文件。
//文件a.c
int global = 10;
int fun()
{...
}
對于上面的全局變量和函數,它們在源文件a.c中被定義,但是如果我想在b.c文件中調用這兩個值也是可以的,具體操作如下。
//文件b.c
extern int global;
extern int fun();
global = 20;
通過加extern關鍵字修飾就可以在本文件中使用另一個源文件中定義的全局變量或者函數了,而且對于全局變量,引入后還可以對其進行修改,修改后的值在后面的代碼中生效。對于通過extern引入的函數,在本文件中就不能再定義同名函數了。
如果像下面這樣通過static函數修飾全局變量和函數,那么即使在另一個文件中通過extern引入,也無法使用,因為static將其限制在本文件使用。
//文件a.c
static int global;
static int fun()
{...
}
也就是說,這個時候你就可以在另一個文件中定義和上面同名的全局變量和函數名稱了,前提是在兩個文件內部的相關變量前都得加上static修飾。
//文件b.c
static int global;
static int fun()
{...
}
現在仔細想一想,其實extern的作用有點類似于頭文件,在源文件中引入頭文件之后,頭文件中的所有內容都會在編譯預處理階段展開,里面的全局變量和函數都可以被使用,但是如果頭文件中只是聲明了函數,那么函數的實現還需要另外一個源文件。extern就是輕量級的引入,而且也少了中間的頭文件過渡,想要什么函數或變量可以通過extern引入到本文件中使用。
對于簡單的文件關系和較少的函數調用,extern或許能夠發揮比較好的作用。