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