为什么实参char **argv与形参const char **p不能相容?
一段代码如下:
1 foo(const char **p)
2
3 main(int argc, char **argv)
4 {
5 foo(argv0);
6 }
编译此段代码,编译器会发出一条警告信息:
Line 5: warning: argument is incompatible with orototype
(第五行:警告:参数与原型不匹配)
事实上,实参char *s与形参const char *p是相容的,标准库所有的字符串处理函数都是这样的。那么为什么实参char **argv与形参const char **p不能相容?答案是肯定的,他们并不相容。回答这个问题破费心机:
在做出最终解释前,有必要更全面的理解const关键字与指针的组合关系。对于如下三种情况:
1、 const double *pd=rates;
2、 double *const pd=rates;
3、 const double *const pd=rates;
其中rates是一个数组名。第一种表示pd为指向const double类型的普通指针,pd指向的值不可改变,但pd本身可变;第二种表示pd为指向double类型的带限定词const的指针,pd指向的值可变,pd本身不可变;第三种表示pd不可变,pa指向的值也不可变。
ANSI C标准中讲述约束条件的小节中描述道:
“每个实参都应该具有自己的类型,这样它的值就可以赋值给与它所对应的形参类型的对象(该对象的类型不能含有限定词)。”这就是说,参数传递过程在某种程度上可以等同于赋值。所以,除非一个类型为char**的值可以赋值给一个const char**类型的对象,否则肯定会产生一条诊断信息。
ANSI C有关简单赋值的描述为:
“要使上述的赋值形式合法,必须满足下列条件之一:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针指向的类型必须具有右边指针所指向类型的全部限定符。”
正因如此,实参char*与形参const char*匹配,但实参const char*与形参char*却不匹配。事实上,正如我们在上面讲到的三种情况中的第一种那样,const float*类型并不是一个有限定符的类型——它的类型是“指向一个具有const限定符的float类型的指针”,也就是说const限定符是修饰指针所指向的类型,而不是指针本身。类似的,const char**也是一个没有限定符的指针类型。它的类型是“指向有const限定词的char类型的指针的指针”,即const char **p中,p是一个指针(指向指针的指针)。当然char**也是没有限定词的,即char **argv中,argv也是一个指针(指向指针的指针)。虽然两种都没有限定词,但是他们所指向的类型却不同(前者指向const char*,后者指向char*),即它们所指向的内容不相容。因此不能将实参char**传递给形参const char**。
浙公网安备 33010602011771号