const char** 與 char** 相容問題

foo(const char** p){}

main(int argc,char** argv){
foo(argv);
}

以上代碼在編譯時會發出一條警告信息
warning :argument is incompatible with prototype

爲什麼會發出這樣的警告呢
要回答這個問題,其實還是挺麻煩的,但咱絕不是複製粘貼

首先形參作爲左值,實參作爲右值

若要使賦值合法,必須具有兩個限定條件*(僅對指針而言,若不是指針,則簡單多了)

1.兩個操作數都是有限定符或者無限定符指針
2.左操作數的指針指向的內容必須具有右邊操作數的指針所指向的內容的全部限定符,

帶着以上兩個原則,我們來分析一下如下代碼

char* cp;
const char* ccp;
ccp = cpp;

左邊操作數是指向const char 類型的指針
右邊的操作數是指向char類型的指針
首先左右操作數都沒限定符,另外const char 的本質是char 與右邊的char兼容,const char作爲左操作數指向的內容,比右邊多了const限定符,當然其實就是說 右操作數限定符 包含於 左操作數限定符
所以以上代碼完全符合條件

但是如果是這樣呢

char** cp;
const char** ccp;
ccp = cp;

左邊的操作數是指向char* 類型的指針
右邊的操作數是指向const char* 類型的指針
所以這兩個操作數都沒有限定符(關於這點請學習一下const的使用規則,下面所說的話都跟這個有關係)
然後問題來了,const char* 與char* 爲什麼不相容呢
const char* 其實是指向const char的指針,char* 其實是指向 char的指針
我們比較一下,const char 與char 本質上都是char,只不過左邊比右邊多了const
const char* 與char*的迷惑之處在於 const char* 看似 是 char* 前加了const,但是請注意,const 是修飾char的,而不是指針的
若要使其成立,可以這麼寫
char** cp;
char*const * ccp;
ccp = cp;

這樣const就是修飾指針的了,代碼也就成立了

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