C C 中const關鍵字

2021-07-30 05:40:22 字數 4705 閱讀 4093

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 修飾符而言,它用來告訴編譯器,被修飾的這些東西,具有唯讀的特點。在編譯的過程中,一旦我們的 試...