問題
#include <stdio.h>
int main()
{
char* name[] = {"hello", "world"};
char **cp = name;
const char** ccp = cp;
return 0;
}
編譯器給出了一條警告:warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] const char** ccp = cp;
,即賦值等號兩邊的類型不相容。
原因
標准中有關合法形式賦值的約束條件:
兩個操作數都是指向有限定符或無限定符的相容類型的指針,左邊指針所指向的類型必須具有右邊指針所指向類型的全部限定符。
而在上述代碼中,指針cp指向的類型為char*
,而指針ccp指向的類型為const char*
,兩個變量所指向的類型不相容,因此編譯器會給出警告。那么為什么char*
與const char*
不相容呢?這是因為const char*
中的const
修飾的不是指針本身,而是指針所指向的對象,類似於int*
與double*
是不相容的。
正確的寫法
#include <stdio.h>
int main()
{
char* name[] = {"hello", "world"};
char **cp = name;
char * const * ccp = cp; // OK
return 0;
}
在上述代碼中,指針ccp指向的類型為char * const
(帶const限定的指向char的指針類型),指針cp指向的類型為char *
(不帶const限定的指向char的指針類型),因此是相容的。
擴展
const與*一起出現的時候,const究竟修飾的是誰呢?
int const * p1; // const修飾的是指針p1所指向的int類型對象
int * const p2; // const修飾的是指針p2
int * const * p3; // const修飾的是指針p3所指向的指針
int * const * const p4; // 第一個const修飾的是指針p4所指向的指針,第二個const修飾的是指針p4
總結成一句話,即const修飾的是其左邊的對象。
參考鏈接