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

时间:2017-05-14 09:35:53

标签: c pointers multidimensional-array function-prototypes

我不擅长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 个答案:

答案 0 :(得分:5)

  

我真的不懂语法。

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

  1. 无法分配数组变量。
  2. 如果一个数组被传递给一个函数,它“衰减”到指向它的第一个元素的指针。
  3. 多维数组只是一个数组数组。因此2D阵列是1D阵列的1D阵列,3D阵列是2D阵列的1D阵列,4D阵列是3D阵列的1D阵列,依此类推...... / LI>
  4. 指向p NT元素数组的指针T (*p)[N]定义为:int 2DArray[7][7] = ...;
  5. 现在为你举例:

    你有

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

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

    a

    然后将其传递给函数。如果发生以下情况/适用:

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

    因此函数的相关变量如下所示:

    pa

    a指向a的第一个元素。作为旁注:从这个指针a,函数不能导出a实际“提供”的元素数量,将说明:{{1}之后有多少有效元素将要跟随的点,所以这也需要传递给函数:

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

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

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

    查看如何定义指向数组的指针:T (*p)[N]我们知道需要派生返回指向数组的指针的函数。函数的defalcation有点需要成为上面的p。因此,将T作为intN作为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];
    

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

    因此,使用PA我们可以代替

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

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

    此版本与上述相同。

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