关于char** 和 const char**
说明: 本文说明的问题在c何c++中都适用。
请参看下面代码:
在vc6.0中会报以下错误:
error C2664: 'foo' : cannot convert parameter 1 from 'char ** ' to 'const char ** '
很多人都认为实参char* s和形参const char*p 应该是相容的,因为标准库中很多字符串函数都是这么用的,为什么实参char** s 和形参 const char**p就不形容呢 ?
分析:
ANSI C 标准第6.3.2.2节中说明中有一句话:
每一个实参应该具有自己的类型,这样它的值可以赋值给与它所对应的形参类型的对象(该对象的类型不能含有限定符)。
由此可知参数传值类似于赋值。参看标准中关于简单赋值部分,第6.3.16.1节 有描述:
要使上述的赋值形式合法,必须满足下列条件之一:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边的指针所指向的类型必须具有右边指针所指向类型的全部限定符。
看下面代码:
char *cp;
const char ** ccp;
ccp = cp;
1) 左操作数ccp是指向 有const限定符的char 类型 的指针。
2) 右操作数cp 是指向 无限定符的char 类型 的指针。
3) 显然char类型和char类型是相容的。ccp 所指向的类型具有cp所指向类型的限定符(无) 和自身的限定符const.
所以 ccp = cp 是合法的,相反 cp = ccp 就会警告。
另外 const char** 是一个没有限定符的指针类型, 它的类型是"指向有const限定符的char类型的指针的指针"。
对于char ** 和 const char ** 都是没有限定符的指针类型,但它们所指向的类型不一样( 前者指向char*, 后者指向 const char*), 因此它们是不相容的。
请参看下面代码:
foo(const char **p){}
main(int argc, char **argv)
{
foo(argv); //error
}
main(int argc, char **argv)
{
foo(argv); //error
}
error C2664: 'foo' : cannot convert parameter 1 from 'char ** ' to 'const char ** '
很多人都认为实参char* s和形参const char*p 应该是相容的,因为标准库中很多字符串函数都是这么用的,为什么实参char** s 和形参 const char**p就不形容呢 ?
分析:
ANSI C 标准第6.3.2.2节中说明中有一句话:
每一个实参应该具有自己的类型,这样它的值可以赋值给与它所对应的形参类型的对象(该对象的类型不能含有限定符)。
由此可知参数传值类似于赋值。参看标准中关于简单赋值部分,第6.3.16.1节 有描述:
要使上述的赋值形式合法,必须满足下列条件之一:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边的指针所指向的类型必须具有右边指针所指向类型的全部限定符。
看下面代码:
char *cp;
const char ** ccp;
ccp = cp;
1) 左操作数ccp是指向 有const限定符的char 类型 的指针。
2) 右操作数cp 是指向 无限定符的char 类型 的指针。
3) 显然char类型和char类型是相容的。ccp 所指向的类型具有cp所指向类型的限定符(无) 和自身的限定符const.
所以 ccp = cp 是合法的,相反 cp = ccp 就会警告。
另外 const char** 是一个没有限定符的指针类型, 它的类型是"指向有const限定符的char类型的指针的指针"。
对于char ** 和 const char ** 都是没有限定符的指针类型,但它们所指向的类型不一样( 前者指向char*, 后者指向 const char*), 因此它们是不相容的。
浙公网安备 33010602011771号