C語言中的const用法以及常量指針與指針常量(有口訣!)

編了這樣的口訣,記住,應該不難:

const(*號)左邊放,我是指針變量指向常量;

const(*號)右邊放,我是指針常量指向變量;

const(*號)兩邊放,我是指針常量指向常量;

指針變量能改指向,指針常量不能轉向!

要是全都變成常量,鎖死了,我不能轉向,你也甭想變樣!

一) 常量指針(對應“左定值”,即const在*的左邊

常量是形容詞,指針是名詞,以指針爲中心的一個偏正結構短語。這樣看,常量指針本質是指針,常量修飾它,表示這個指針乃是一個指向常量的指針(變量)。

指針指向的對象是常量,那麼這個對象不能被更改。

在C/C++中,常量指針是這樣聲明的:

1)const int *p;

2)int const *p;

常量指針的使用要注意,指針指向的對象不能通過這個指針來修改,可是仍然可以通過原來的聲明修改,也就是說常量指針可以被賦值爲變量的地址,之所以叫做常量指針,是限制了通過這個指針修改變量的值。


二) 指針常量(對應“右定向”,即const在*的右邊

指針是形容詞,常量是名詞。這回是以常量爲中心的一個偏正結構短語。那麼,指針常量的本質是一個常量,而用指針修飾它,那麼說明這個常量的值應該是一個指針。

指針常量的值是指針,這個值因爲是常量,所以不能被賦值。

在C/C++中,指針常量這樣聲明:

int a;

int *const b = &a; //const放在指針聲明操作符的右側

只要const位於指針聲明操作符右側,就表明聲明的對象是一個常量,且它的內容是一個指針,也就是一個地址。上面的聲明可以這麼讀,聲明瞭一個常量b,它的值是變量a的地址(變量a的地址,不就是指向變量a的指針嗎)。

因爲指針常量是一個常量,在聲明的時候一定要給它賦初始值。一旦賦值,以後這個常量再也不能指向別的地址。

雖然指針常量的值不能變,可是它指向的對象是可變的,因爲我們並沒有限制它指向的對象是常量。

因此,有這麼段程序:

char *a = "abcde1234";

char *b = "bcde";

char *const c = &a;

  下面的操作是可以的。

  a[0] = 'x'; // 我們並沒有限制a爲常量指針(指向常量的指針)

或者

*c[0] = 'x' // 與上面的操作一致



例一

下面分別用const限定不可變的內容是什麼?
1)const在前面
const int nValue; //nValue是const
const char *pContent; //*pContent是const, pContent可變
const char* const pContent; //pContent和*pContent都是const
2)const在後面,與上面的聲明對等
int const nValue; //nValue是const
char const * pContent; //*pContent是const, pContent可變
char* const pContent; //pContent是const,*pContent可變
char const* const pContent; //pContent和*pContent都是const
答案與分析:
const和指針一起使用是C語言中一個很常見的困惑之處,在實際開發中,特別是在看別人代碼的時候,常常會因爲這樣而不好判斷作者的意圖,下面講一下我的判斷原則:
const只修飾其後的變量,至於const放在類型前還是類型後並沒有區別。如:const int a和int const a都是修飾a爲const。注意*不是一種類型,如果*pType之前是某類型,那麼pType是指向該類型的指針
一個簡單的判斷方法:指針運算符*,是從右到左,那麼如:char const * pContent,可以理解爲char const (* pContent),即* pContent爲const,而pContent則是可變的。[1] 

例二

int const * p1,p2;
p2是const;(*p1)是一整體,因此(*p1)是const,但p1是可變的。int * p1,p2只代表p1是指向整型的指針,要表示p1、p2都是指針是需寫成int * p1,* p2。所以無論是* const p1,p2還是const * p1,p2,裏面的*都是屬於p1的。

例三

int const * const p1,p2;
p2是const,是前一個const修飾的,*p1也被前一個const修飾,而p1被後一個const修飾。

例四

int * const p1,p2;
p1是const,(* const p1)是整體,所以const不修飾p2。

例五

指針指向及其指向變量的值的變化
const在*的左邊,則指針指向的變量的值不可直接通過指針改變(可以通過其他途徑改變);在*的右邊,則指針的指向不可變。簡記爲“左定值,右定向”
1)指針指向的變量的值不能變,指向可變
int x = 1;
int y = 2;
const int* px = &x;
int const* px = &x; //這兩句表達式一樣效果
px = &y; //正確,允許改變指向
*px = 3; //錯誤,不允許改變指針指向的變量的值
2)指針指向的變量的值可以改變,指向不可變
int x = 1;
int y = 2;
int* const px = &x;
px = &y; //錯誤,不允許改變指針指向
*px = 3; //正確,允許改變指針指向的變量的值
3)指針指向的變量的值不可變,指向不可變
int x = 1;
int y = 2;
const int* const px = &x;
int const* const px = &x;
px = &y; //錯誤,不允許改變指針指向
*px = 3; //錯誤,不允許改變指針指向的變量的值

補充

在c中,對於const定義的指針,不賦初值編譯不報錯,
int* const px;這種定義是不允許的。(指針常量定義的時候對其進行初始化)
int const *px;這種定義是允許的。(常指針可以再定義的時候不初始化)
但是,在C++中
int* const px;和const int* const px;會報錯,const int* px;不報錯。
必須初始化指針的指向int* const px = &x;const int* const px=&x;
強烈建議在初始化時說明指針的指向,防止出現野指針!
   
注意:當與 typedef 配合使用時,情況又變!!
例如:下面的代碼編譯器會報一個錯誤,請問,哪一個語句是錯誤的呢?
typedef char * pStr; //不能理解爲簡單的替換!!
char string[4] = "bbc";
const char *p1 =" string"; //1式
const pStr p2 =" string"; //2式
p1++;
p2++;
答案與分析:
問題出在p2++上。
1)const使用的基本形式: const type m;限定m不可變。替換基本形式中的m爲1式中的*p1,替換後const char *p1;限定*p1不可變,當然p1是可變的,因此問題中p1++是對的。替換基本形式中的type爲2式中的pStr,替換後const pStr m;限定m不可變,題中的pStr就是一種新類型,因此問題中p2不可[1] 變,p2++是錯誤的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章