C/C++中修飾符const、extern、static、volatile的用法
來自:網易博客 http://afericazebra.blog.163.com/blog/static/30050408200801494053866/
1.const的用法:
爲什麼使用const?
採用符號常量寫出的代碼更容易維護;
指針常常是邊讀邊移動,而不是邊寫邊移動;
許多函數參數是隻讀不寫的。
const最常見用途是作爲數組的界和switch分情況標號(也可以用枚舉符代替)
用法1:常量
取代了C中的宏定義,聲明時必須進行初始化。const限制了常量的使用方式,並沒有描述常量應該如何分配。如果編譯器知道了某const的所有使用,它甚至可以不爲該const分配空間。最簡單的常見情況就是常量的值在編譯時已知,而且不需要分配存儲。―《C++ Program Language》
用const聲明的變量雖然增加了分配空間,但是可以保證類型安全。
C標準中,const定義的常量是全局的,C++中視聲明位置而定。
用法2:指針和常量
使用指針時涉及到兩個對象:該指針本身和被它所指的對象。將一個指針的聲明用const“預先固定”將使那個對象而不是使這個指針成爲常量。要將指針本身而不是被指對象聲明爲常量,必須使用聲明運算符*const。
所以出現在 * 之前的const是作爲基礎類型的一部分:
char *const cp; // 到char的const指針
char const *pc1; // 到const char的指針
const char *pc2; // 到const char的指針(後兩個聲明是等同的)
從右向左讀的記憶方式:
cp is a const pointer to char.
pc2 is a pointer to const char.
用法3:const修飾函數傳入參數
將函數傳入參數聲明爲const,以指明使用這種參數僅僅是爲了效率的原因,而不是想讓調用函數能夠修改對象的值。同理,將指針參數聲明爲const,函數將不修改由這個參數所指的對象。
通常修飾指針參數和引用參數:
void Fun( const A *in); // 修飾指針型傳入參數
void Fun(const A &in); // 修飾引用型傳入參數
用法4:修飾函數返回值
可以阻止用戶修改返回值。返回值也要相應的付給一個常量或常指針。
用法5:const修飾成員函數
const對象只能訪問const成員函數,而非const對象可以訪問任意的成員函數,包括const成員函數;
const對象的成員是不能修改的,而通過指針維護的對象卻是可以修改的;
const成員函數不可以修改對象的數據,不管對象是否具有const性質。編譯時以是否修改成員數據爲依據進行檢查。
2.static的用法:
靜態變量作用範圍在一個文件內,程序開始時分配空間,結束時釋放空間,默認初始化爲0,使用時可以改變其值。
靜態變量或靜態函數只有本文件內的代碼才能訪問它,它的名字在其它文件中不可見。
用法1:函數內部聲明的static變量,可作爲對象間的一種通信機制
如果一局部變量被聲明爲static,那麼將只有唯一的一個靜態分配的對象,它被用於在該函數的所有調用中表示這個變量。這個對象將只在執行線程第一次到達它的定義時初始化。
用法2:局部靜態對象
對於局部靜態對象,構造函數是在控制線程第一次通過該對象的定義時調用。在程序結束時,局部靜態對象的析構函數將按照他們被構造的相反順序逐一調用,沒有規定確切時間。
用法3:靜態成員和靜態成員函數
如果一個變量是類的一部分,但卻不是該類的各個對象的一部分,它就被成爲是一個static靜態成員。一個static成員只有唯一的一份副本,而不像常規的非static成員那樣在每個對象裏各有一份副本。同理,一個需要訪問類成員,而不需要針對特定對象去調用的函數,也被稱爲一個static成員函數。
類的靜態成員函數只能訪問類的靜態成員(變量或函數)。
3.extern的用法
extern可以聲明其他文件內定義的變量。在一個程序裏,一個對象只能定義一次,它可以有多個聲明,但類型必須完全一樣。如果定義在全局作用域或者名字空間作用域裏某一個變量沒有初始化,它會被按照默認方式初始化。
將變量或函數聲明成外部鏈接,即該變量或函數名在其它函數中可見。被其修飾的變量(外部變量)是靜態分配空間的,即程序開始時分配,結束時釋放。
在C++中,還可以指定使用另一語言鏈接,需要與特定的轉換符一起使用。
extern “C” 聲明語句
extern “C” { 聲明語句塊 }
extern 表明該變量在別的地方已經定義過了,在這裏要使用那個變量。
static 表示靜態的變量,分配內存的時候,存儲在靜態區,不存儲在棧上面。static 作用範圍是內部連接的關係,和extern有點相反,它和對象本身是分開存儲的,extern也是分開存儲的,但是extern可以被其他的對象用extern 引用,而static 不可以,只允許對象本身用它。
4.volatile的用法
類型修正符(type-modifier),限定一個對象可被外部進程(操作系統、硬件或併發進程等)改變。volatile與變量連用,可以讓變量被不同的線程訪問和修改。
聲明時語法:
int volatile vInt;
常用於像中斷處理程序之類的異步進程進行內存單元訪問。
除了基本類型外,對用戶定義類型也可以用volatile類型進行修飾。
注意:可以把一個非volatile int賦給volatile int,但是不能把非volatile對象賦給一個volatile對象。
一個有volatile標識符的類只能訪問它接口的子集,一個由類的實現者控制的子集。用戶只能用const_cast來獲得對類型接口的完全訪問。此外,volatile向const一樣會從類傳遞到它的成員。