extern f (int a[4][5]);
与数组类型定义的参数是在编译时调整所以真的指针类型,具体的指针数组的元素类型面对错误。在这种情况下,int a[4][5]
是一个由4个元素组成的数组,每个元素都是一个由5个元素组成的数组。调整后,实际类型是指针的5 int
阵列,所以上述是完全等效于:
extern f(int (*a)[5]);
注意,4
被自动忽略。 (说得客气一点,这不是我最喜欢的C语言功能)。
现在你申报的20 int
秒的数组:
int b[20];
,并尝试将其传递到f
:
void func (void)
{
f (b);
}
由于b
是数组类型的表达式,因此它(在大多数情况下并不是所有情况下)都会隐式转换为指向数组第一个元素的指针。 (当数组表达式是sizeof
的操作数,一元的&
,或者它是一个用于初始化数组的字符串文本时,这些例外情况都是如此)。
f(&b[0]);
的说法是int*
类型,这是不符合预期的类型int(*)[5]
兼容的:所以这个调用:以
f(b);
等同。
如果f
的参数类型是固定的,那么您需要将它传递给一个数组的指针。例如,您可能会更改b
的定义,以便与f
预期相符。
以下是我可能会写它:
extern f (int (*a)[5]);
int b[4][5];
void func (void)
{
f(b);
}
我已经改变了的f
的声明,以便更清楚地表明实际的参数类型,我已经重新定义b
为2维数组。 b
仍然包含20 int
元素,但它是不同类型的。
请记住,这里有两个不同的数组/指针语言规则。一个是阵列类型的参数是,调整后(在编译时),以便它真的是指针类型。另一个是在大多数但不是所有的上下文中,数组类型的表达式都被隐式地转换为指向数组第一个元素的指针。
这两个规则一起工作,混淆新的C程序员关于数组和指针之间的关系。
另见comp.lang.c FAQ的第6部分。
当参数的类型为int(*)[5]'时,'b'的类型是'int *'。这有点糟糕。更改原型或传递正确的参数。 – Mahesh