我只是在C语言中遇到了这个函数调用/声明对,我有点困惑(我是这里的新手,但是在我用来学习的任何材料中我都没有看到这个问题。 )。函数声明为bool read_matrix(double a[][M], int n, int m)
,但由read_matrix((double (*)[M]) a, n, m)
调用。 (M是由#define
设置的整数。)这些参数如何相互排列?因此,(*)[M]是什么类型的对象?
感谢您消除混乱。
当函数参数声明为类似于此函数声明的数组类型时
bool read_matrix(double a[][M], int n, int m);
然后由编译器调整为指向元素类型的指针。
因此此函数声明等同于声明
bool read_matrix(double ( *a )[M], int n, int m);
另一方面,在表达式中使用的数组标识符(例如,用作参数)则转换为指向其第一个元素的指针。
因此,如果在函数的调用程序中,您有一个声明为类似的数组
double a[N][M];
然后传递给类似的函数
read_matrix( a, N, M );
它被转换为指向类型为int ( ^ )[M]
的第一个元素的指针。
关于您显示的通话中的演员表
read_matrix((double (*)[M]) a, n, m)
然后,如果a
是如上所述声明的数组,则强制转换是多余的。这种转换是隐式进行的。
除非它是sizeof
,_Alignof
或一元&
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则expression类型为“ N” -T
“的元素数组将被转换(“衰变”)为类型为“ T
的指针”的表达式,该表达式的值将成为数组第一个元素的地址。
当将数组表达式作为函数参数传递时,函数实际接收的是指针值:
void foo( T *a ) // equivalent to T a[] and T a[N]
{
...
}
int main( void )
{
T arr[N];
...
foo( arr );
...
}
作为一种“方便”,C允许您对函数参数声明使用数组表示法,但要注意,由于参数is是指针值而不是数组,因此它将被“调整”为指针声明- T a[N]
和T a[]
将被解释为T *a
。请注意,在函数参数声明中,这是only true,而不是常规变量声明。
[现在,只为咯咯笑,将T
替换为数组类型double [M]
。因此,T
不再是arr
的N元素数组,而是现在是double
的M元素数组的N元素数组:
int main( void )
{
double arr[N][M];
...
foo( arr );
...
}
在对foo
的调用中,表达式arr
从“类型为double
的M元素数组的N元素数组”到“指向double
的M元素数组的指针”“衰减”,或者double (*)[M]
。因此我们的foo
声明如下:
void foo( double (*a)[M] ) // equivalent to double a[][M] and double a[N][M]
{
...
}
这就是为什么这两个看似不同的声明是等效的-在函数参数声明的上下文中,double a[][M]
被解释为double (*a)[M]
。同样,这仅适用于函数参数声明,不适用于常规变量声明。