此函数如何调用和定义排列?

问题描述 投票:0回答:2

我只是在C语言中遇到了这个函数调用/声明对,我有点困惑(我是这里的新手,但是在我用来学习的任何材料中我都没有看到这个问题。 )。函数声明为bool read_matrix(double a[][M], int n, int m),但由read_matrix((double (*)[M]) a, n, m)调用。 (M是由#define设置的整数。)这些参数如何相互排列?因此,(*)[M]是什么类型的对象?

感谢您消除混乱。

c pointers multidimensional-array implicit-conversion function-declaration
2个回答
1
投票

当函数参数声明为类似于此函数声明的数组类型时

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是如上所述声明的数组,则强制转换是多余的。这种转换是隐式进行的。


0
投票

除非它是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]。同样,这仅适用于函数参数声明,不适用于常规变量声明。

© www.soinside.com 2019 - 2024. All rights reserved.