最近在看《C专家编程》,书中提到:
1、实参 char *s与形参 const char *p相容;
2、实参char **argv 与形参 const char **p 不相容;(why ?)
代码如下:
<span style="font-size:14px;">#include "stdafx.h"
int foo(const char **p)
{
printf("just for test");
return 0;
}
int main(int argc,char*argv[])
{
foo(argv);
return 0;
}</span>
编译报错:error C2664: 'foo' : cannot convert parameter 1 from 'char *[]' to 'const char **'
ANSI C11 第6.5.2.2节(ANSI C89第6.3.2.2节)提到:
“ If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters. Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter.”
如果表示被调函数的表达式其类型包含原型,则实参数必须和形参相匹配。每个实参的类型必须保证其实参值可以赋值给一个对象,而该对象的类型是相应的形参类型的非限定版本。
接着,ANSI C11 第6.5.16.1节(ANSI C89 第6.3.16.1节)描述了合法的赋值条件:
One of the following shall hold:
— the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
— the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible
with the type of the right;
— the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand
would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of
compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
— the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand
would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to
a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type
pointed to by the right;
— the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
— the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.
其第三条描述:“两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针所指向类型的全部限定符”。
以上,解释了:在函数调用中,实参char *能够与形参const char *匹配。反之,const char *不能对char *进行赋值。
在ANSI C11 第6.2.5节(ANSI C89 第6.1.2.5节)描述:
The type designated as ‘‘float *’’ has type ‘‘pointer to float’’. Its type category is pointer, not a floating type. The const-qualified version of this type is designated as ‘‘float * const’’ whereas the type designated as ‘‘const float *’’ is not a qualified type — its type is ‘‘pointer to const-qualified float’’ and is a pointer to a qualified type.
由“ float * ”指示的类型是“ 指向float的指针 ”,它的类型类别是指针,而不是浮点类型。该类型的const限定形式由“ float * const ”指示。而由“ const float * ”指示的类型不是限定类型——该类型是“ 指向const限定的float的指针”,是一个指向限定类型的指针。
以此类推,const char ** 也是一个没有限定符的指针类型。它的类型是:“指向有const限定符的char类型的指针的指针”。由于char ** 和const char **都是没有限定符的指针类型,但是它们所指向的类型是不一样的(前者指向char *,后者指向const char *),因此它们是不相容的。
以上参考 ANSI C11及ANSI C89,及《C专家编程》。
编译环境:32位Windows 7+VS2008
ZhaiPillary
2015/05/20于上海 博客地址:http://blog.csdn.net/pillary