为什么实参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**。

posted on 2016-03-08 11:33  lxbcute  阅读(1413)  评论(0)    收藏  举报

导航