const經常被用到,所以今天總結一下const關鍵字的用法,常用的場景為修飾變數(c/c++不同),修飾指標和引用,修飾函式引數,修飾函式返回值,修飾函式定義體(類 成員函式)
(1)修飾變數
cosnt在修飾變數時,在c和c++中是不同的。
const
int a = 5;
intarray[a];//在c語言中是錯誤的,因為在c語言中是定義了乙個唯讀變數
intarray[a];//在c++中是正確的,因為在c++中定義了乙個常量
c中,const是乙個不能被改變的普通變數,既然是變數,就要占用儲存空間,所以編譯器不知道編譯時的值.而且,陣列定義時的下標必須為常量.
而c++中的const正常情況下是看成編譯期的常量,編譯器並不為const分配空間,只是在編譯的時候將期值儲存在名字表中,並在適當的時候折合在**中. 所以在c++中const修飾的量可以用在陣列的定義中。
在c語言中: const int size; 這個語句是正確的,因為它被c編譯器看作乙個宣告,指明在別的地方分配儲存空間.
但在c++中這樣寫是不正確的,會報錯
c++中const預設是內部連線,如果想在c++中達到以上的效果,必須要用extern關鍵字. c++中,const預設使用內部連線.而c中使用外部連線.
內連線:編譯器只對正被編譯的檔案建立儲存空間,別的檔案可以使用相同的表示符或全域性變數.c/c++中內連線使用static關鍵字指定.
外連線:所有被編譯過的檔案建立一片單獨儲存空間.一旦空間被建立,聯結器必須解決對這片儲存空間的引用.全域性變數和函式使用外部連線.通過extern關鍵字宣告,可以從其他檔案訪問相應的變數和函式.c++中,是否為const分配空間要看具體情況. 如果加上關鍵字extern或者取const變數位址,則編譯器就要為const分配儲存空間.
c++中定義常量的時候不再採用define,因為define只做簡單的巨集替換,並不提供型別檢查.
(2)修飾指標和引用
2.1修飾指標
使用const修飾指標時,由於const的位置不同,而含意不同。如果const位於的左側,則const就是用來修飾指標所指向的變數,即指標指向為常量;如果const位於的右側,const就是修飾指標本身,即指標本身是常量。
可能有點繞,舉幾個例子來說明一下。
int a = 10;
int b = 20;
//const在*左邊,常量指標
const
int * p1 = &a;
intconst *p2 = &a;
*p1 = 30;//錯誤,因為const修飾的是p1指向的值,不能通過p1修改,但是可以通過a來修改。
a = 20; //正確
//const 在*右邊,指標常量
int * const p3 = &a;
p3 = &b; //錯誤,因為const修飾的是p3指標,所以p3的指向不能修改
*p3 = 20; //正確
2.2修飾引用使用const修飾符也可以說明引用,被說明的引用為常引用,該引用所引用的物件不能被更新。其定義格式如下:
const 《型別說明符》 & 《引用名》
例如:
const double & v;
在實際應用中,常指標和常引用往往用來作函式的形參,這樣的引數稱為常引數。這個看下面的修飾函式引數時再詳細講解
(3)修飾函式引數
首先如果該引數用於輸出,那麼無論是採用指標傳遞還是引用傳遞,都不能加const修飾。所以const只能用於修飾輸入引數。這裡又分三種情況:輸入引數採用值傳遞還是指標傳遞還是引用傳遞。
3.1採用值傳遞
如果採用值傳遞,由於函式將自動產生臨時變數用於複製該引數,該輸入引數本來就無需保護,所以不需要加const 修飾。
例如,對於函式void func1(int x),寫成void func1(const int x)一點意義也沒有。同理,對於void func2(a a)也不需要寫成void func2(const a a),其中a為使用者自定義的物件型別。
3.2採用指標傳遞
如果採用指標傳遞,那麼加const可以防止函式體內部對該引數進行改變,起到保護作用。
例如某個 stringcopy 函式:
void stringcopy(char *strdestination, const char *strsource);
其中 strsource 是輸入引數,strdestination 是輸出引數。給 strsource 加上 const 修飾後,如果函式體內的語句試圖改動 strsource 的內容,編譯器將指出錯誤。
3.3採用引用傳遞
首先我們來說一下,為什麼要引入引用傳遞這種方法。原因是:對於非內部資料型別的引數而言,象void func(a a) 這樣宣告的函式注定效率比較底。因為函式體內將產生a 型別的臨時物件用於複製引數a,而臨時物件的構造、複製、析構過程都將消耗時間。為了提高效率,可以將函式宣告改為void func(a& a)。這樣一來,根據引用傳遞的定義,只是借用了引數的別名,不需要產生臨時物件。
但是,這樣一來,當函式體中改變了引數a的值後,相應的傳遞的原始值也會相應改變。所以如果不希望改變原始引數,只需要在前面加上const修飾,這樣一來,函式最終定義為void func(const a& a)。同理,是否應將void func(int x) 改寫為void func(const int &x),以便提高效率?完全沒有必要,因為內部資料型別的引數不存在構造、析構的過程,而複製也非常快,「值傳遞」和「引用傳遞」的效率幾乎相當。
總結一下const作為函式輸入引數的用法:
對於非內部資料型別的輸入引數,應該將「值傳遞」的方式改為「const 引用傳遞」,目的是提高效率。例如將void func(a a) 改為void func(const a &a)。
對於內部資料型別的輸入引數,不要將「值傳遞」的方式改為「const 引用傳遞」。否則既達不到提高效率的目的,又降低了函式的可理解性。例如void func(int x) 不應該改為void func(const int &x)。
(4)修飾函式返回值
根據上面的思路,這裡也分三種情況,即值傳遞、指標傳遞、引用傳遞。
如果函式返回值採用「值傳遞」方式,由於函式會把返回值複製到外部臨時的儲存單元中,加const 修飾沒有任何價值。
例如,不要把函式int getint(void) 寫成const int getint(void)。同理不要把函式a geta(void) 寫成const a geta(void),其中a 為使用者自定義的資料型別。
如果函式返回值採用「指標傳遞」方式,那麼函式返回值(即指標)的內容不能被修改,該返回值只能被賦給加const 修飾的同型別指標。
例如,定義函式為:const char *getstring(void),那麼char *str = getstring()將會出現編譯錯誤。應該寫成const char *str = getstring()。
如果函式返回值是採用「引用傳遞」方式,它的意義在於能提高效率,而這種方式使用場合並不多。這個時候,一定要搞清楚函式究竟是想返回乙個物件的「拷貝」還是僅返回「別名」就可以了,否則程式會出錯。
例如,對於**類的過載賦值函式**a & operate = (const a &other),如果不加cons修飾,則定義a a, b, c;(a = b) = c,程式合法,但是如果加上const修飾,即const a & operate = (const a &other),則程式會報錯。
(5)修飾成員函式
const 成員函式的宣告看起來怪怪的:const 關鍵字只能放在函式宣告的尾部,大概是因為其它地方都已經被占用了。
但事實上,任何不會修改資料成員(即函式中的變數)的函式都應該宣告為const 型別。如果在編寫const 成員函式時,不慎修改了資料成員,或者呼叫了其它非const 成員函式,編譯器將指出錯誤,這無疑會提高程式的健壯性。
例如下面的類myclass的成員函式getcount():
class myclass ;
這裡,在函式定義頭後面加上的 const 表示這個函式是乙個「唯讀函式」,函式不能改變類物件的狀態,不能改變物件的成員變數的值。如在函式體中不能這麼寫:
classname :: getcount( )
編譯器將指出getcount 函式中的錯誤,因為試圖修改資料成員member。同樣,const成員函式也不能在函式中呼叫其他非const 的函式。
總結一下const成員函式:
1. const物件只能呼叫const成員函式
2. 非const物件可以呼叫const和非const成員函式,不過優先呼叫非 const成員函式
3. 對於加上mutable修飾符的資料成員,const成員函式可以修改
C C 中const關鍵字詳解
1 問題描述 2 解答 不用死記!理解記憶 遇到const修飾的時候,從右向左讀 最容易區分 如 const int p1 則const 修飾的是int p1說明這個變數是不能變的,就是p1所指向的變數是常量變數 int const p2 i const修飾的是 p2 表示所指向的變數 說明p2所指...
C C 中const關鍵字相關
ansi c 允許使用const關鍵字來宣告 常量 const 常量 和普通變數一樣,只是它們的值不能修改。該處 常量 加引號的原因是,const變數只是read only,不能修改其值,的普通變數,只能用於允許使用變數的地方。故在編譯器沒有進行常量摺疊的時候 一般的c語言編譯器,也有其他的可以定義...
C C 中 const 關鍵字用法總結
首先,來看看const的基本含義。在 c c 語言中,const關鍵字是一種修飾符。所謂 修飾符 就是在編譯器進行編譯的過程中,給編譯器一些 要求 或 提示 但修飾符本身,並不產生任何實際 就 const 修飾符而言,它用來告訴編譯器,被修飾的這些東西,具有唯讀的特點。在編譯的過程中,一旦我們的 試...