问题
#includeint 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*
是不相容的。
正确的写法
#includeint 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修饰的是指针p2int * const * p3; // const修饰的是指针p3所指向的指针int * const * const p4; // 第一个const修饰的是指针p4所指向的指针,第二个const修饰的是指针p4
总结成一句话,即const修饰的是其左边的对象。