【问题标题】:Why can't I pass a 2D array as a pointer to pointer but can pass a 1D array as a pointer为什么我不能将二维数组作为指针传递,但可以将一维数组作为指针传递
【发布时间】:2018-11-23 08:26:35
【问题描述】:

显然这段代码有效

void printD(int * ar,int r)
    {
        for(int i = 0; i < r; i++)
            cout<<ar[i]<<endl;
    }
int main()
{
    int ar[3] = {1,2,3};
    printD(ar,3);
    return 0;
}

但是这段代码不起作用

void print2D(int ** ar,int r,int c)
    {
        for( int i = 0; i< r;i++)
            for(int j = 0; j < c;j++)
            cout<<ar[i][j]<<endl;
    }
int main()
{

   int ar2[1][2] = {{3,1}};
   print2D(ar2,1,2);
    return 0;
}

我不明白为什么这不起作用?

【问题讨论】:

  • 二维数组不是指向指针的指针。它是一个指向二维数组的指针。
  • 这是比 C++ 更多的 C 代码(cout 除外)。如果你真的想使用 C++,你应该考虑使用标准容器 (std::vector)。并传递参考资料。
  • 在 KR C 语言的旧时代,我们经常使用 int ar2[2][2] = {{3,1},{2, 4}} 之类的可怕的东西; print1D((int *) ar2, 4);不向孩子展示,但它正在工作......最好定义自己的矩阵类型,或使用库
  • 前一个可怕的例子有助于理解为什么ar[2][2]不是int **

标签: c++ arrays pointers multidimensional-array


【解决方案1】:

问题在于如何计算内存地址。 a[0]是第一个元素,a[1]是第二个元素,所以a[1]的地址就是a[0]的位置加上元素的大小。这里没问题,任何元素的地址都可以通过第一个元素的位置乘以偏移量乘以元素大小来计算。

这如何与多维数组一起工作? a[0][5]a[1][5] 之间的距离是多少?好吧,这取决于行的大小(为了这个例子,我使用这个术语,实际上,没有任何“行”),因为最后它只是一个内存块。如果一行有 10 个元素,那么距离是元素大小的 10 倍。所以这个行大小很重要,没有它就无法计算数组中元素的确切位置。现在在这里:

void print2D(int ** ar,int r,int c)

它怎么知道行的大​​小? ar[1][0] 是第二行的第一个元素,因此如果一行的大小为 10,那么它将是内存块中的第 10 个元素。但是,如果行大小为 20,那么它将是第 20 个元素,这将是一个不同的地址。那它怎么知道呢?

代码不起作用,因为它需要信息来计算地址,但它没有这些信息。

【讨论】:

    【解决方案2】:

    这个数组int ar2[1][2]实际上衰减到int(*)[2]

    没有中间指针指向被分配的指针,有一个连续的 1D 数组可以在 2D 中访问,因此剩余的 [2] 提供了从一行到另一行的跨度。

    【讨论】:

      【解决方案3】:

      二维数组被隐式转换为指向一维数组的指针,而不是指向指针的指针。

      void print2D(int (*ar)[2],int r,int c)
      {
           //  definition omitted for brevity
      }
      int main()
      {
      
         int ar2[1][2] = {{3,1}};
         print2D(ar2,1,2);
         return 0;
      }
      

      也没有从指向数组的指针(如上例)到指向指针的指针的转换。

      对于更多维度,这也有效 - 除了第一个维度以外的所有维度必须在编译时知道。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-28
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-24
        相关资源
        最近更新 更多