概念:
連接:在一個執行程序中,標識符代表存放變量或者被編譯過的函數體的存儲空間。連接用鏈接器所見的方式描述存儲空間。連接的方式有兩種,內部鏈接和外部鏈接:
內部鏈接意味著只對正被編譯的文件創建存儲空間。用內部鏈接,別的文件可以使用相同的標識符或全局變量,鏈接器不會發現沖突——也就是為每一個標識符創建單獨的存儲空間。在C和C++眾內部鏈接由關鍵字static指定。
外部鏈接意味著為所有被編譯過的文件創建一片單獨的存儲空間。一旦創建存儲空間,鏈接器必須解決所有這片存儲空間的引用。全局變量和函數名有外部鏈接。通過用關鍵字extern生命,可以從其他文件訪問這些變量和函數。函數之外定義的所有變量(C++中除了const,const 默認為內部鏈接,明確的聲明可以改變為外部鏈接)和函數定義,默認為外部鏈接。局部變量只存在對戰中,所以沒有鏈接。
1、Static
靜態變量作用范圍在一個文件內,只有本文件內的代碼才能訪問它,它的名字在其它文件中不可見。程序開始時分配空間和初始化,結束時釋放空間,使用時可以改變其值。實現的時候不需要static的修飾,因為static是聲明性關鍵字;
static關鍵字是C, C++中都存在的關鍵字, 它主要有三種使用方式, 其中前兩種只指在C語言中使用, 第三種在C++中使用(C,C++中具體細微操作不盡相同, 本文以C++為准).
(1)局部靜態變量 :全局數據區分配內存,只初始化一次,全局生命期
(2)外部靜態變量/函數 :不能被其它文件訪問的全局變量和函數,但為了限制全局變量/函數的作用域,
(3)靜態數據成員/成員函數:表示屬於一個類而不是屬於此類的任何特定對象的變量和函數.
2、extern
extern是C/C++語言中表明函數和全局變量作用范圍(可見性)的關鍵字,它告訴編譯器,其聲明的函數和變量可以在本模塊或其它模塊中使用。
1。對於extern變量來說,僅僅是一個變量的聲明,其並不是在定義分配內存空間。如果該變量定義多次,會有連接錯誤
2。通常,在模塊的頭文件中對本模塊提供給其它模塊引用的函數和全局變量以關鍵字extern聲明。也就是說c文件裡面定義,如果該函數或者變量與開放給外面,則在h文件中用extern加以聲明。所以外部文件只用include該h文件就可以了。而且編譯階段,外面是找不到該函數的,但是不報錯。link階段會從定義模塊生成的目標代碼中找到此函數。
3。與extern對應的關鍵字是static,被它修飾的全局變量和函數只能在本模塊中使用。
以下三個關鍵字是相關的,其中const-volatile也被合稱為c-v限定符。
3、volatile
volatile的作用: 作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值。同const一樣,volatile是一個類型修飾符。
4、const
限定一個變量(所有變量,包含:成員變量,參數變量,局部變量,全局變量,返回值)不允許被改變。const限定中最麻煩的是可能是指針的限定,需要多加關注。與const對應的關鍵字是mutable。
5、mutable
用於類的非靜態非const數據成員,表示不受到成員函數的const的限制,可以在const成員函數中使用。
下面試其他函數限定符
6、inline
inline只會影響函數在translation unit(可以簡單理解為C源碼文件)內的編譯行為,只要超出了這個范圍inline屬性就沒有任何作用了。所以inline關鍵字不應該出現在函數聲明 中,沒有任何作用不說,有時還可能造成編譯錯誤;inline關鍵字僅僅是建議編譯器做內聯展開處理,而不是強制。
7、explicit
這個關鍵字修飾構造函數聲明,表示顯式構造函數(模版),顯式構造函數不參與特定的重載。C++11從兩個角度擴展了用法。其一是適用於轉換函數(模版),類似構造函數,避免不需要的重載。其二是列表初始化,除非直接使用std::initializer_list,顯式構造函數被列表初始化忽略(在C++98/03中,explicit僅對單一參數調用構造函數有意義,這裡打破了這個限制)。