兩個比較容易混淆的概念。
const
int* p;
int*
const p;
intconst
* p;
這是常見的三種寫法,按照從左至右的順序記憶,按照從右至左的順序理解。
只關注const 和 * 的先後先後順序,const讀做常量,*讀做指標。
參考《effective c++》item21上的做法,如果const位於星號的左側,則const就是用來修飾指標所指向的變數,即指標指向為常量;如果const位於星號的右側,const就是修飾指標本身,即指標本身是常量。
比如
const
int* p;
// 常量指標
int*
const p;
// 指標常量
intconst
* p;
// 常量指標
將 * 讀做指向。
const
int* p;
// p指向乙個const
int*
const p;
// 常量p 指向乙個 int
intconst
* p;
// p指向乙個const
int
*const p;
// 常量p 指向乙個 int
重點在「常量」,這是乙個常量,也是乙個指標,也就是說,這個指標一旦指向了乙個位址,那麼它就不可以再指向別的位址空間。
const
int* p;
// p指向乙個const
intconst
* p;
// p指向乙個const
重點在「指標」,這是乙個用const修飾的指標,它既可以指向常量,也可以指向變數。
所謂的「常量」指標或者「常量」引用,不過是指標或引用「自以為是」罷了,只是不能通過該指標或引用來修改物件的值。
code:
int a =15;
const
int*p =
&a; cout <<
*p << endl;
output:
15
int a =15;
const
int*p =
&a;*p =10;
// 通過常量指標修改
cout <<
*p << endl;
output:
編譯報錯
int a =15;
const
int*p =
&a; a =10;
// 通過變數自身修改
cout <<
*p << endl;
output:
10
對於乙個指標物件來說,它本身可以是const的,也就是說它只可以指向初始化的位址,不可以再指向其他位址空間。另外,指標所指的物件也可以是const的,這就叫底層const,也就是說它所指的位址空間或者物件是不可以通過它修改的(前邊說過,這是「自以為是」的)。
在執行拷貝操作時,頂層const不受影響,拷入和拷出的物件是否是常量沒有關係。
而底層const不可以,拷入和拷出的物件必須具有相同的底層const資格,或者兩個物件的資料型別必須能夠轉換,一般來說,非常量可以轉換為常量,反之則不行。
幾個轉換的例子
// 變數宣告
const
int v2 =0;
int v1 = v2;
int*p1 =
&v1,
&r1 = v1;
const
int*p2 =
&v2,
*const p3 =
&i,&r2 = v2;
// 下列哪些是合法的?
r1 = v2;
// 合法
p1 = p2;
// 不合法,p1是變數,p2是底層const。二者要麼都有底層const,要麼是變數賦給常量。
p2 = p1;
// 合法, p1是變數,p2是底層const。執行的是變數轉到常量。
p1 = p3;
// 不合法,p1是變數,p3是頂層const+底層const,二者要麼都有底層const,要麼是變數賦給常量。
p2 = p3;
// 合法,p2是底層const,p3是頂層const+底層const,二者都有底層const資格。
使用const修飾變數以後,該變數就成為了乙個常量。使用賦值的方式對該變數直接進行修改是行不通的。但是可以通過變數的位址進行修改(做一次強制型別轉換)。
const
int a =2;
int*p =
const_cast
<
int*
>
(&a);(
*p)++
;cout << a << endl;
cout <<
(*p)
<< endl;
上邊**輸出的是
2
3
為什麼?
再次輸出變數a的位址和p所指向的位址,也是相同的。但是輸出的時候a卻顯示3。原因在於:c++中的常量摺疊。指const變數(即常量)值放在編譯器的符號表中,計算時編譯器直接從表中取值,省去了訪問記憶體的時間,從而達到了優化。
C 指標常量 常量指標和常指標常量
1 指標常量 如果在定義指標變數時候,指標變數前用const修飾,被定義的指標變數就變成了乙個指標型別的常變數,指標型別的常變數簡稱為指標常量。格式如下 資料型別 const 指標變數 變數名 修飾符const與指標變數緊鄰,說明指標變數不允許修改,既然指標變數的值不能修改,所以一定要在定義的時候給...
c 指標常量 和 常量指標
指標常量 指向常量的位址,不允許改變指向位址,指向位置的變數值能被改變 p不可以變 const p 常量指標 指向常量的指標,指標指向的物件不能通過這個指標來修改,可是仍然可以通過原來的宣告修改,也就是說量指標可以被 賦值為變數的位址,之所以叫做常量指標,是限制了通過這個指標修改變數的值 cont ...
C 指標常量和常量指標
首先在c 目前我看到的型別宣告方式,該變數的型別都是由最後幾個字來確定,前面是定語,修飾詞。有其他不同的歡迎指出,共同學習 比如 指標陣列 是陣列,陣列裡存的是指標。陣列指標 是指標,指標指向陣列。所以指標常量 首先是常量,然後是乙個指標,即是該指標是乙個常量,指標的值即位址不會變。常量指標 首先是...