extern 與 static 關鍵字的完整說明

 
在CSDN見到有問extern和static關鍵字作用的,我做了完整的解答,順便轉貼過來與大家探討

==============================
先分清C和C++再解釋,有不同之處

1. C語言:

1.1. 首先要明確三個概念:
聲明vs定義 —— 聲明只規定對象的“類型”,定義則規定了對象的“實體”。一個對象,聲明可以無窮多次,定義只能一次!
作用域 —— 指對象的“存取權限”
存儲方式 —— 指變量爲“靜態數據段DS”或“堆棧段”變量

1.2. 對變量(變量有“存儲方式”的問題):
extern:聲明/定義變量,作用域=全局,存儲方式=DS
static:定義變量,作用域=局部,存儲方式=DS

extern聲明的同時給變量賦了初值,那就同時做了定義,否則就只是聲明
所以
extern int var = 0;
之類的東西是不應該出現在.h文件裏的,而且在一個程序裏只能出現一次,否則就是重複定義了

static變量如果出現在函數內,作用域只在函數內,否則就是當前文件。

函數內用static局部變量的意圖不在於作用域,而在於將存儲方式強制規定爲靜態,使“再入”時仍保持上一次的值。同一函數的所有“副本”都公用一個該變量的實體,因此使用了static變量的函數一般是“不可再入”的,不是“多線程安全”的。

1.3. 對函數(函數無所謂“存儲方式”):
extern:聲明/定義函數,作用域=全局
static:聲明/定義函數,作用域=局部
extern/static如果只跟函數原型,就是聲明,如果跟了函數體,就是定義。(有人不知道static也可以只聲明不定義)
如果聲明時指定了extern或static的,定義時可以省略extern/static,如果不省略,必須一致。

2. C++語言:
C++是C的超集,所以包含了上述特性,只是多了在類中使用static,和extern "C"的用法
類中使用static將成員聲明爲“靜態”,類static成員的作用域是全局的,而非局部的(當然受privite/protected限制),且該類所有實體公用一個static成員實體,意圖在於存儲方式,不在作用域。
與其它成員不同,static成員需要單獨的實體定義。
與C語言不同,類static成員在定義時,不能再用static修飾。

extern "C" 則是爲了C++與C混合編程而設的


C/C++語言的extern/static/auto等關鍵字將聲明/定義/作用域/存儲方式等職能混在一起,爲了減少關鍵字數量而沒有分工,不規則,規定複雜,實在是給初學者出難題,我個人覺得設計得不好(但也許是能做到的當中最好的了),我見過編了十幾年C程序的人還是有不會用的時候。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章