繁体   English   中英

函数原型在C中返回2D数组

[英]function prototype return 2D array in C

我不是很擅长C而且我对双阵列很困惑。 下面是我有一个问题的代码大纲。 Main函数调用CreateRandConn函数,并将一个填充0的2D数组作为参数传递给它。 CreateRandConn函数将2D数组作为参数,将2DArray中的某些值从0更改为1,并将更改后的2DArray返回给main。 我想在函数原型中指出CreateRandConn函数的返回类型是一个2D数组。 我该如何表明? 我真的不懂语法。 我写错了什么? 我传递2DArray作为函数头中的参数的方式是不正确的? 如果是这样,我怎么写呢? 我仍然对指针和双数组之间的关系感到困惑。 有人可以用下面的代码大纲来解释它吗? 希望有人知道我的问题是什么......

//Function prototype
int ** CreateRandConn(char * RandRoom[7], int my2DArray[7][7], char * room_dir);

//Function
int ** CreateRandConn(char * RandRoom[7], int my2DArray[7][7], char * room_dir)
{
   ...
   return my2DArray;
}

int main()
{
   int 2DArray[7][7] = {0}; 
   2DArray = CreateRandConn(RandRoomArray, my2DArray[7][7], room_dir);
   return 0;
}

我真的不懂语法。

好的,让我们回顾一下基础知识:

  1. 无法分配给数组变量。
  2. 如果数组传递给函数,它会“ 衰减 ”到指向其第一个元素的指针。
  3. 多维数组只是一个数组数组。 因此,2D阵列是1D阵列的1D阵列,3D阵列是2D阵列的1D阵列,4D阵列是3D阵列的1D阵列,依此类推......
  4. 指向类型为TN元素数组的指针p定义为: T (*p)[N]

现在为你举例:

你有

int 2DArray[7][7] = ...;

为了清楚起见,我将其改为

int a[5][7] = ...;

所以这会传递给一个函数。 如果发生以下情况/适用:

  • 在上面的1.之后,不可能传递一个数组,好像有可能将它分配给函数内部的变量,因为无法分配数组,无法传递数组。
  • 在上面的2.之后,该函数需要将相关变量定义为“ 指向数组第一元素的指针 ”。
  • 在上面的3.之后, a的第一个元素是int [7]
  • 在上面的4.之后,指向int[7]的指针将被定义为: int(*)[7]

所以函数的相关变量看起来像:

... func(int (*pa)[7])

pa指向a的第1个元素。 作为一个侧面说明:从这个指针a函数不能获得多少元素a实际上是“规定”,会说:有多少一前一后有效的元素a点,将遵循,所以这需要传递给函数,以及:

... func(int (*pa)[7], size_t rows)

从目前为止我们学到的步骤来看,一个数组没有被传递,只是指向它的第一个元素* 1被传递,被复制到函数的局部变量(这里是pa )。

由此直接得出一个数组不能作为函数的返回值传回,而只是一个指向数组元素的指针(通常是第一个)

看看如何定义指向数组的指针: T (*p)[N]我们知道需要派生返回指向数组的指针的函数。 函数的defalcation有点需要成为上面的p 因此,将T作为int ,将N作为7,我们得到:

int (*func(int (*pa)[7], size_t rows))[7];

那么简单的实现和用法将是:

#include <stdlib.h> /* for size_t */

#define ROWS (5)
#define COLS (7)

int (*func(int (*pa)[COLS], size_t rows))[COLS];

int (*func(int (*pa)[COLS], size_t rows))[COLS]
{
  for (size_t i = 0; i < rows; ++i)
  {
    for (size_t j = 0; j < COLS; ++j)  
    {
      pa[i][j] = 0;
    }
  }

  return pa;
}

int main(void)
{
  int a[ROWS][COLS];

  int (*pa)[COLS] = func(a, ROWS);

  return EXIT_SUCCESS;
}

* 1(虽然草率,但经常被错误地称为“ 指向数组的指针被传递 ”, 一般情况下它不是 ,但就在这里,因为它是一个2D数组,会说数组的元素本身就是数组)。


如果您理解了上述内容,那么仅仅是为了完整性,遵循上述函数声明的不太奇怪的外观(但也可能是教育程度较低;-))。 它可以通过使用typedef构造声明,隐藏数组指针的某种复杂声明作为参数和返回类型。

这个

typedef int (*PA)[COLS];

定义一个指向intCOLS数组的类型。

所以使用PA我们可以代替

int (*func(int (*pa)[COLS], size_t rows))[COLS];

PA func(PA pa, size_t rows))[COLS];

此版本与上述相同。

是的,它看起来更简单,但带来的事实是,指针pa和函数的返回值)只能通过查看它们的定义而无法识别为指针。 许多程序员认为这种结构被认为是“不好的做法”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM