關於const與指針搭配使用的一點記錄

const限定符指定了一個變量爲只讀變量,是不容許被改變的,所以const變量在定義時就必須初始化。
const在與指針搭配時,使用將變的複雜和微妙。簡單的說const搭配指針就會出現如下三種狀況:ide

  • 指向const變量(對象)的指針
  • const指針
  • 指向const變量(對象)的const指針

1.指向const變量(對象)的指針
指針指向了const變量,例如 const int *ptr或者int const *ptr,這兩種寫法含義同樣,這表示const限定了ptr所指向的數據類型,而並不是ptr自己。即ptr自己並非const.能夠對ptr從新賦值,無需在定義時初始化。
指向const變量的指針能夠指向一個const變量,也能夠指向一個非const變量,固然指針類型與變量類型要一致。無論指向了一個const變量仍是非const變量,任何企圖經過這個指針去修改變量的值都會致使編譯錯誤。同時,const變量只能賦給指向const變量的指針,賦給一個普通變量也是不容許的。
如(代碼僅供理解const,不要刻意追求是否正確可執行):wordpress

const int *ptr;
int *ptr_1;
const int a=12;
const int b=13;
int c=14;
ptr=&a;/*指向const變量*/
ptr=&b;/*從新賦值指向const變量*/
*ptr=20;/*error,不能經過ptr修改*/
ptr=&c;/*從新賦值指向非const變量*/
ptr_1=&c;/*普通指針指向普通變量*/
ptr_1=&a;/*error,普通指針不能指向const變量*/指針

《C++ Primer》中對此有詳細的解釋,儘管不能經過指向const對象的指針去修改基礎對象,然而若是該指針指向的是一個非const對象,能夠用其餘方法修改所指的對象。以下的例子:對象

const int *ptr;
int *ptr_1;
int c=14;
ptr=&c;
printf("c=%d\n",*ptr);
ptr_1=&c;
*ptr_1=18/*經過非指向const的指針修改*/
printf("c=%d\n",*ptr);string

輸出結果能夠看到兩次輸出是不同的。對此,《C++ Primer》中說,若是把指向const的指針理解爲「自覺得指向const的指針」,這可能會對理解有所幫助。it

2.const指針編譯

int a=12;
int *const ptr=&aclass

這意味着ptr這個指針被定義成const變量,必須在定義時初始化,並不能從新對ptr賦值,即不能將ptr再指向其餘變量。可是,*ptr=13,這樣的操做徹底取決與a是否是一個const變量,在這個例子中不是,因此*ptr=13是正確的,假如a這樣定義,const int a=12,*ptr=13會致使錯誤。基礎

3.指向const變量(對象)的const指針變量

const int a=12;
const int *const ptr=&a;

這就意味着ptr不能被從新賦值,由於它是const指針,定義時需初始化;同時不能經過ptr修改a,由於a也是const變量。

4.有趣的typedef

typedef string *pstring;
const pstring cstr;

這時,cstr是一個指向string類型的const指針,而不是一個指向const string的普通指針。由於const pstring cstr;,const修飾的是pstring這個類型,而這個類型是一個string指針。其實:

string s;
typedef string *pstring;
/*如下三個定義相同,都是指向string的const指針*/
const pstring cstr1=&a;
pstring const cstr2=&a;
string *const cstr3=&a;

5.記憶方法
記憶方法其實很簡單,只需看清const和*的位置就能夠,const在前,則是指向const變量的指針,如:

const int *ptr;int const *ptr;

*在前,則是const指針,如:

int *const ptr;

兩個const,則是指向const的const指針了,如:

const int *const ptr;

相關文章
相關標籤/搜索