搞懂頂層const和底層const

JaysonWang發表於2019-05-14

C語言雖然簡單,但是重難點還是很多的,就比如讓需要新手比較蛋疼的指標問題,但是深入學習之後指標才是碰到的第一個攔路虎,也是最簡單的一個。比如宣告問題,頂層const和底層const。今天說說後者。

宣告問題可以理解為複雜指標,函式指標的宣告和解讀問題

int (*f(int, int))(int);
// f 是一個有兩個int型別引數的函式,函式返回指向具有一個引數為int型別,返回型別為int的函式指標

以下有幾個栗子

int iVal = 520;
// 第一個栗子
const int *pVal1 = &iVal;
// 第二個栗子
int const *pVal2 = &iVal;
// 第三個栗子
int * const pVal3 = &iVal;
// 第四個栗子
int const * const pVal4 = &iVal;

分析

首先我們說說頂層const和底層const的通俗定義
頂層const: 表示指標本身是個常量,更簡單的說頂層const作用對物件本身,表示物件自身是一個常量
底層const: 表示指標所指向的物件是個常量

所以有以下結論(個人總結)

將const考慮成向右結合

  • 如果const右結合修飾的為型別或者*,那這個const就是一個底層const

  • 如果const右結合修飾的為識別符號,那這個const就是一個頂層const

const的影響

2017-02-11 更新: 書寫錯誤

int const * const p;
      ^       ^
      1       2
  • 底層const(上述程式碼中1的位置)主要影響的是指向的物件

    • 頂層const表示為不能修改所指向的物件的值,即,所指向的物件是一個常量。

  • 頂層const(上述程式碼中2的位置)主要影響的是物件本身

    • 表示物件本身不能被修改,即,物件(指標)本身是個常量,但是可以修改指標所指向的物件的值。

理解以上前提為要理解指標其實也是一個物件(int),這個物件的值是所要指向的物件的地址。
比如
物件 A 的地址 = 0x123456,物件 A 的值 = "ABCDEF"
指標 B 指向 物件 A
所以指標 B 的地址 = 0x234567, 指標 B 的值 = 0x123456
系統在棧或者堆中分配,因為指標本身是一個物件,也有屬於自己的地址,所以可以有指向指標的指標
注意區別指標和引用

栗子分析

第一個和第二個栗子

const int *pVal1 = &iVal;
// const 右結合修飾 int ,所以這個const為底層const
int const *pVal2 = &iVal;
// const 右結合修飾 * ,所以這個const為底層const

第三個栗子

int * const pVal3 = &iVal;
// 這個const右結合修飾 pval3 ,修飾的是一個識別符號,所以這個const為頂層const

第四個栗子

int const * const pVal4 = &iVal;
// 第一個const修飾的是 * 所以第一個const是底層const
// 第二個const修飾的是 pVal4 所以這個const是頂層const

相關文章