C 这个函数调用和定义是如何排列的?
我刚刚在C中遇到了这个函数调用/声明对,我有点困惑(我在这里是一个新手,但我在学习的任何材料中都没有看到这个问题)。函数声明以C 这个函数调用和定义是如何排列的?,c,pointers,multidimensional-array,implicit-conversion,function-declaration,C,Pointers,Multidimensional Array,Implicit Conversion,Function Declaration,我刚刚在C中遇到了这个函数调用/声明对,我有点困惑(我在这里是一个新手,但我在学习的任何材料中都没有看到这个问题)。函数声明以bool read_matrix(double a[][M],int n,int M)形式给出,但它由read_matrix((double(*)[M])a,n,M)调用。。(M是由#define设置的整数)这些参数如何相互对齐?就这一点而言,(*)[M]是什么类型的对象 感谢您消除了混淆。当函数参数使用类似于此函数声明中的数组类型声明时 bool read_matrix
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);
然后编译器将其调整为指向元素类型的指针
所以这个函数声明与声明是等价的
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
、\u Alignof
或一元&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则将转换类型为“T的N元素数组”的表达式(“Decage”)指向类型为“指向T
”的表达式,表达式的值将是数组第一个元素的地址
将数组表达式作为函数参数传递时,函数实际接收的是指针值:
void foo( T *a ) // equivalent to T a[] and T a[N]
{
...
}
int main( void )
{
T arr[N];
...
foo( arr );
...
}
为了“方便”,C允许您使用数组表示法声明函数参数,但请注意,它将被“调整”为指针声明,因为参数是指针值,而不是数组-TA[N]
和TA[]
将被解释为T*a
。请注意,这仅在函数参数声明中是正确的,而不是在正则变量声明中
现在,只是为了好玩,将T
替换为数组类型double[M]
。因此,arr
现在不再是T
的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]
。同样,这仅适用于函数参数声明,而不是正则变量声明 (*)[M]
是一个数组,因为当传递给函数时,像a[N][M]
这样的数组会衰减为指向像(*ptr)[M]
这样的数组的指针