【问题标题】:How to send a 2-D array as a reference in C++, and back?如何在 C++ 中发送二维数组作为参考,然后返回?
【发布时间】:2011-09-24 23:18:29
【问题描述】:

又是一个初学者到中级的问题。我正在尝试将二维数组传递给 C++ 中的函数。我知道数组不能直接发送到函数,所以我首先创建了一个指针(名称已编辑,但你会明白的):

double input[a][b] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
Class.calculate (*(input), a, b);

然后我尝试在所述函数中使用它 - 但似乎我不知道如何取消引用指针以便能够再次处理二维数组。我的代码(或多或少):

for (int x=0; x<=a; x++){
    for (int y=0; y<=b; y++){
        tmpInput[x][y]= (*input)[x][y];
    }
}

编译器报错,即invalid types ‘double[int]’ for array subscript,但我还是想不通。我最好的选择是我没有正确取消引用二维数组,但另一个选择是 C++ 不能直接取消引用二维数组,而是依赖于在发送之前将数组转换为一维数组。有什么想法吗?

【问题讨论】:

  • 当然,您可以“将数组发送到函数”。只需将其声明为“**double”(如 littleadv 建议的那样)或等效地声明为“*double[]”(如 Mahesh 建议的那样)。
  • @paulsm4:我尝试了@littleadv 的建议,并声明了calculate(double** input, int a, int b),并用Class.calculate(input, a, b); 调用它。没用:error: no matching function for call to ‘Class::calculate(float [(((unsigned int)(((int)a) + -0x00000000000000001)) + 1)][(((unsigned int)(((int)b) + -0x00000000000000001)) + 1)], int&amp;, int&amp;)’
  • 您可能想要x &lt; a 而不是x &lt;= ayb 相同)。

标签: c++ pointers multidimensional-array


【解决方案1】:

为什么数组不能直接发送给函数?

调用 Class.calculate (*(input), a, b); 正在尝试取消引用 input,因为它不是指针,所以您不能这样做。

如果calculate被定义为:

Class::calculate(double *input[], size a, size b)

您可以拨打Class.calculate(input, a, b)

【讨论】:

    【解决方案2】:

    我知道数组不能直接发送给函数,所以我首先创建了一个指针(名称已编辑,但你会明白的)

    错了。你可以通过它。只需将calculate 成员函数的第一个参数设为指向指针的指针即可。

    calculate( double **ptr, int rows, int columns ){
    
       // Now access the array via ptr as usual with the [] operator. 
       // like ptr[0][1]
    }
    

    并将其称为 - Class.calculate (input, a, b);

    【讨论】:

    • 好的...但是,我如何发送参数,Class.calculate (*(input), a, b);Class.calculate (input, a, b);
    • Class.calculate(input, a, b); 一样,因为二维数组衰减为指向指针的指针。严格来说是指向第一行的指针。
    【解决方案3】:

    还没有人谈论模板吗?我很失望!


    您实际上可以将它作为真正的引用传递,而无需在 C++ 中将大小作为额外参数传递:

    class Class{
    public:
      // ...
      template<unsigned N, unsigned M>
      void calculate(double (&arr)[N][M]){
        // use it like normal, arr[x][y]
        // ...
      }
      // ...
    };
    

    Example on Ideone.

    尽管这不能回答您提出的确切问题,但了解这些内容总是好的。 :) 模板毕竟是 C++ 的重要组成部分,无论您是初学者、中级还是专业人士。您从第一天开始就使用它们,尽管可能是不知情的。

    【讨论】:

    • 作为记录,我的课程代码(或多或少)发布在ideone.com/LZiAY(感谢 Ideone 的建议!)。抱歉,没时间学习模板,我只有三天的时间来学习 WxWidgets 和文件操作,然后再分发这项工作。
    【解决方案4】:

    如果没有看到calculate() 的声明,很难确定,但我猜这是参数类型不匹配。您可以将数组作为double* 发送,但不能作为double** 发送 - 它 一个双精度数组(它们在内存中线性排列,即使编译器允许您处理它们作为多维数组)。但它不是指向双精度的指针数组,这正是double** 类型的实际含义:取消引用double**,你得到一个double*

    如果您知道第二个下标是常量(在您的情况下为 2),您可以定义 calculate() 以期望 N*2 的双精度数组:

    void calculate(double array[][2], int a)
    {
        //Whatever
    }
    

    或者,如果两个维度都可以改变,只需直接使用 double* 并自己进行指针数学运算(在调用此函数时,您可能必须将数组转换为 double*,但它会起作用):

    void calculate(double* array, int a, int b)
    {
        //To get array[i][j]:
        array[i * b + j];
    }
    

    希望这会有所帮助!

    【讨论】:

    • 几乎成功了!不幸的是,有一个错误:当我尝试发送数组时,而不是被视为float*(抱歉,自发送问题以来更改了类型),它被视为float [(((unsigned int)(((int)xMax) + -0x00000000000000001)) + 1)][(((unsigned int)(((int)h) + -0x00000000000000001)) + 1)](在此处插入“lolwut”)跨度>
    • @Carlos - 我已经四处寻找方法来做到这一点,但没有任何好的方法。 this thread 的第二篇文章总结得很好——你有三个选择,但没有一个是你想要的:1)事先知道你的尺寸。 2) 调用函数时显式转换为 float*。 3)使用“指向浮点指针(float**)的指针”设置。或者看看你是否可以重新组织你的代码并使用一维数组并为自己省去很多麻烦。干杯!
    • 我所做的是将二维数组重构为一维数组;因为我已经通过了两个维度的最大尺寸,所以创建float[a*x+b] 很容易......或者是float[b*x+a]
    【解决方案5】:

    使用 Boost.MultiArray:

    http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html

    它们支持视图、范围、迭代器,它们抽象出内存管理,但仍然保持高度可配置性。您可以像您期望的那样通过引用传递 multi_arrays。

    如果您想了解原始指针(或者您正在编写需要适应 64k 内存或其他内容的嵌入式应用程序),那么编写使用它们的代码是个好主意。如果您想编写可维护的生产代码,那么最好使用 STL/Boost 并避免使用原始指针,除非在不太可能需要大量阅读的代码中。

    【讨论】:

      猜你喜欢
      • 2019-04-01
      • 2022-01-16
      • 1970-01-01
      • 2023-03-14
      • 2023-01-10
      • 1970-01-01
      • 2021-12-24
      • 2014-12-22
      • 1970-01-01
      相关资源
      最近更新 更多