發布時間:2011-09-16 共1頁
char **p和const char **p是兩種不相容的類型,因為它們是兩種不同的類型。如果你理解這句話,可以不用往下看了。
先看這個代碼:
1 foo(const char **p){ }
2
3 void main(int argc, char **argv)
4 {
5 foo(arvg);
6 }
如果編譯這段代碼,編譯器會發出一條警告消息:
line 5:warning argument is incompatible with prototype
(第5行:警告:參數與原型不匹配)。
疑問是:實參char *s與形參const char *p是相容的(標準庫中所有的字符串處理函數都是這個樣子的),為什么實參char **argv與形參const char **p不相容呢?
答案是,它們并不相容。
在ANSI C標準中有這么一句話:每個實參都應該具有自己的類型,這樣它的值就可以賦值給與它所對應的形參類型的對象(該對象的類型不能含有限定符)。
這就是說參數傳遞過程類似于賦值。所以,除非一個類型為char **的值可以賦值給一個const char **類型的對象,否則肯定會產生一條診斷信息。要使以上賦值合法,必須滿足下列條件之一:
兩個操作數都是指向有限定符或無限定符的相容類型的指針,左邊指針所指向的類型必須具有右邊指針所指向類型的全部限定符。
正是這個條件,使得函數調用中實參char *能夠與形參const char*匹配。
1 char *cp;
2 const char *ccp;
3 ccp = cp; //right
4 cp = ccp; //產生編譯警告
要想徹底理解為何char ** 與 const char **是不相容的,我們得先回顧一下const float *:它并不是一個有限定符的類型——它的類型是“指向一個具有const限定符的float類型的指針”,也就是說const限定符是修飾指針所指向的類型,而不是指針本身。
類似的,const char **也是一個沒有限定符的指針類型。它的類型是“指向有const限定符的char類型的指針的指針”。
由于char **和const char **都是沒有限定符的指針類型,但它們所指向的類型不一樣(前者指向char*,后者指向const char*),因此它們是兩種不同的類型,是不相容的。因此,類型為char **的實參與類型為const char **的形參是不相容的。它違反了上文黑體字所列出的約束。
說明:在VC、VS里面編譯第一個程序的話,0個warning,0個錯誤。在Linux下面用gcc編譯的話,會給出實參和形參不相容的warning。 這是不是說明微軟家的編譯器不好呢?