【问题标题】:2D array passing via pointers in C通过 C 中的指针传递的二维数组
【发布时间】:2014-07-29 16:40:25
【问题描述】:

下面是我的代码,其中我将名为 a 的数组传递给仅显示数组的显示函数。

我在此声明 printf("Arr[%d][%d] is %d\n",i,j,*(*(q+i)+j)); 上收到 invalid type argument of type unary * 错误

但是,注释代码会正确打印值。你能解释一下我做错了什么吗?我是 C 的新手,如果这是一个愚蠢的错误/错误,请原谅我。

#include <stdio.h>
void display(int *, int, int);
int main()
{
    int a[3][4] = {
                            {1,2,3,4},
                            {5,6,7,8},
                            {9,10,11,12}
                            };
    display(a,3,4);
    /*
    int i,j;

    for(i=0; i<3; i++)
        {
            for(j=0; j<4; j++)
                printf("Arr[%d][%d] is %d\n",i,j,*(*(a+i)+j));
        }
    */
    return 0;
}
void display(int *q, int row, int col)
{
    int i,j;

    for(i=0; i<row; i++)
        {
            for(j=0; j<col; j++)
                printf("Arr[%d][%d] is %d\n",i,j,*(*(q+i)+j));
        }
}

【问题讨论】:

    标签: c arrays function pointers multidimensional-array


    【解决方案1】:

    解决此问题的另一种方法是显式传递数组的地址并取消引用它 (display()),但也可以在没有额外间接级别的情况下实现所需的结果 (display1()):

    #include <stdio.h>
    
    void display(const size_t row, const size_t col, int (*pa)[row][col]);
    void display1(const size_t row, const size_t col, int a[row][col]);
    
    int main(void)
    {
      int a[3][4] = {
        {  1,  2,  3,  4 },
        {  5,  6,  7,  8 },
        {  9, 10, 11, 12 } 
      };
    
      display(3, 4, &a);
      display1(3, 4, a);
    
      return 0;
    }
    
    void display(const size_t rows, const size_t cols, const int (*pa)[row][col]);
    {
      for (size_t i = 0; i < rows; ++i)
      {
        for (size_t j = 0; j < cols; ++j)
        {
          printf("Arr[%zu][%zu] is %d\n", i, j, (*pa)[i][j]);
        }
      }
    }
    
    void display1(const size_t rows, const size_t cols, const int a[row][col]);
    {
      for (size_t i = 0; i < rows; ++i)
      {
        for (size_t j = 0; j < cols; ++j)
        {
          printf("Arr[%zu][%zu] is %d\n", i, j, a[i][j]);
        }
      }
    }
    

    更新:这至少需要一个兼容 C99 的编译器。

    【讨论】:

    • 只是一个间接太多,我的口味。
    • 看起来是更干净的方式,你!
    【解决方案2】:

    您唯一的问题是您调用显示的方式。您需要在传递数组时删除索引并修复显示的初始定义以匹配:

    #include <stdio.h>
    
    void display(int q[][4], int, int);
    
    int main()
    {
        int a[3][4] = {
                                {1,2,3,4},
                                {5,6,7,8},
                                {9,10,11,12}
                                };
    
        display (a, 3, 4);
    
        return 0;
    }
    void display(int q[][4], int row, int col)
    {
        int i,j;
    
        for(i=0; i<row; i++)
            {
                for(j=0; j<col; j++)
                    printf("Arr[%d][%d] is %d\n",i,j,*(*(q+i)+j));
            }
    }
    

    输出:

    Arr[0][0] is 1
    Arr[0][1] is 2
    Arr[0][2] is 3
    Arr[0][3] is 4
    Arr[1][0] is 5
    Arr[1][1] is 6
    Arr[1][2] is 7
    Arr[1][3] is 8
    Arr[2][0] is 9
    Arr[2][1] is 10
    Arr[2][2] is 11
    Arr[2][3] is 12
    

    【讨论】:

      【解决方案3】:

      在现代 C 中,您应该首先传递尺寸的大小

      void display(size_t row, size_t col, int (*q)[col]);
      

      然后您可以像使用q[i][j] 一样正常使用q,并为您完成所有索引计算。

      void display(size_t row, size_t col, int (*q)[col]) {
          for(size_t i=0; i<row; i++) {
                  for(size_t j=0; j<col; j++)
                      printf("Arr[%zu][%zu] is %d\n", i, j, q[i][j]);
              }
      }
      

      这需要至少 C99 才能工作。

      【讨论】:

      • 是的,我熟悉这种访问元素的方式 (q[i][j]),但是我希望学习使用指针来访问。感谢您指出如何将二维数组传递为 (*q)[col] :)
      • 但是这里唯一依赖于 C99 的是循环内的变量声明?这与问题无关:数组指针语法应该适用于任何版本的 C。数组指针的 col 数组大小似乎至少被 gcc -std=c89 忽略了。
      • 没关系,-pedantic-errors 让 gcc 表现得应有尽有。有趣的是gcc -std=c89 允许您使用 VLA:s。
      【解决方案4】:

      一般来说,要将2D 数组传递给函数,您需要为除第一个维度之外的所有维度指定数组维度,因此在此示例中,您需要将[4] 作为最后一个维度,但您可以选择省略它第一维,即

      void display( int (*q)[4], int row, int col)
      

      并将上述声明如下

      void display(int (*)[], int, int);
      

      【讨论】:

      • 谢谢,正是我想要的!但是你能告诉我 (*q) 是什么意思吗?我知道最后一个维度是必需的,但是 (*q) 是做什么用的?
      • 如果指定维度,则不需要数组指针语法。 void display( int q[][4], int row, int col) 可能更容易阅读。
      • @Lundin 是的,不需要。而且void display( int q[][4], int row, int col) 更容易。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多