【问题标题】:how to pass 2 dimensional array if both dimensions are unknown at compile time如果在编译时两个维度都未知,如何传递二维数组
【发布时间】:2012-08-16 06:49:27
【问题描述】:

传递未知大小的二维数组的正确方法是什么?

reprVectorsTree::reprVectorsTree(float tree[][], int noOfVectors, int dimensions)

如何在函数后面访问这个数组的元素?

如何从调用函数传递一个二维数组?

-----编辑----

我想处理数组,因为调用是从 c 代码完成的,并且有一个 c 到 c++ 的接口

-----编辑----- 如何定义从调用函数传递一个二维数组?

float tree[15][2] = {{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1}};

reprVectorsTree *r1 = new reprVectorsTree(tree[0][0],8,2);

上面的代码有什么问题? 我得到一个无法将参数 1 从 'float' 转换为 'float **'

【问题讨论】:

  • 那么你只需要使用float **
  • 您应该将标签从“C++”更改为“C”

标签: c++ c multidimensional-array


【解决方案1】:

使用指针..

     reprVectorsTree(tree, noOfVectors, dimensions);// Calling function.

功能定义:

reprVectorsTree(float **tree, int noOfVectors, int dimensions){


}

我认为这对你会有帮助。

【讨论】:

  • 请注意,tree 应声明为指针数组,而不是静态 2D 浮点数组。否则代码将无法编译。
  • 是的。你说的对。我以为他(问问题的人)知道这个声明。
  • @user494461:您刚刚在 reprVectorsTree 函数中传递了值。这里你必须传递数组或者你必须改变函数定义。
  • 不,这根本不起作用,float** 和 float[][] 是非常不同的动物。
【解决方案2】:

如果大小未知,您可以使用简单的float *tree 指针指向一维数组。然而,转向特定元素的语法与 2D 数组不同:

reprVectorsTree::reprVectorsTree(float *tree, int noOfVectors, int dimensions)
{
    ...
    tree[ row_number * dimensions + column_number ] = 100.234;
}

在调用代码中你会有这样的东西:

float d2array[ROWS][COLUMNS];
...
reprVectorsTree(&d2array[0][0], ROWS, COLUMNS);

更新

考虑以下传递二维数组的不同方法的示例:

#include <iostream>
#include <malloc.h>

float test[2][4] = 
{
   {3.0, 4.0, 5.0, 0},
   {6.0, 7.0, 8.0, 0}
};

void print(float *root, int rows, int columns)
{
   for (int row = 0; row < rows; ++row)
   {
      for (int col = 0; col < columns; ++col)
      {
         std::cout << root[row * columns + col ] << " ";
      }
      std::cout << std::endl;
   }
}

float *test2[2] = 
{
   &test[0][0],
   &test[1][0],
};

void print2(float **root, int rows, int columns)
{
   for (int row = 0; row < rows; ++row)
   {
      for (int col = 0; col < columns; ++col)
      {
         std::cout << root[row][col] << " ";
      }
      std::cout << std::endl;
   }
}

int main()
{
   print(&test[0][0], 2, 4);
   //print(test2, 2, 4); // doesn't work

   print2(test2, 2, 4);
   //print2(&test[0][0], 2, 4); // doesn't work
   //print2(&test[0], 2, 4); // doesn't work

   float **dynamic_array = (float **)malloc(2 * sizeof(float *));
   dynamic_array[0] = (float *)malloc(4 * sizeof(float));
   dynamic_array[1] = (float *)malloc(4 * sizeof(float));

   for (int row = 0; row < 2; ++row)
   {
      for (int col = 0; col < 4; ++col)
      {
         dynamic_array[row][col] = (float)(row * 4 + col);
      }
   }

   print2(dynamic_array, 2, 4);
   //print(dynamic_array, 2, 4); // doesn't work

   return 0;
}

【讨论】:

  • reprVectorsTree(&d2array[0][0], ROWS, COLUMNS); - 我无法从浮点数转换为浮点数**
  • 您需要将 root 描述为 float * 才能使用这种方法。
【解决方案3】:
#include <iostream>
using namespace std;

int
main(void)
{
    int layers = 3; // can be calculated in run-time
    int elem = 5; // can be calculated in run-time
    int* pArray = new int[layers * elem];
    /* usage */
    for (int i = 0; i < sizeof(pArray) / sizeof(pArray[0]); ++i) // traverse through layers
    {

        for (int j = 0; j < sizeof(pArray[0])/ sizeof(int); ++j) // traverse through elements in layer
        {
            // do some stuff
        }
    }
}

【讨论】:

    【解决方案4】:

    在现代C中,从C99开始,就是这么简单

    void foo(size_t n, size_t m, double A[n][m]) {
      //
    }
    

    然后给你。您唯一需要记住的是,大小必须位于参数列表中的数组之前。

    为了避免在调用方的堆栈上分配这样的野兽,你应该这样做

    double (*A)[m] = malloc(sizeof(double[n][m]));
    

    这样的“矩阵”可以像您习惯的那样使用A[i][j] 之类的东西,而对foo 的调用看起来就像

    foo(n, m, A);
    

    【讨论】:

    • 我得到一个错误 - 我这样做的预期常量表达式
    • 那么您没有符合 C99 的编译器。唯一仍然存在且大量使用的是 MS,是吗?
    【解决方案5】:

    第一个想法是使用向量。但如果您使用的是 C 代码,请将其作为 reprVectorsTree(float** tree, int noOfVectors, int dimensions) 传递。

    对于您的情况:

    float tree[15][2] = {{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1},{2,1}};
    
    int nRows = 15;
    int nCols = 2;
    
    float** arr = new float*[nRows];
    
    for (int i = 0; i < nRows; ++i) {
         arr[i] = new float[nCols];
    }
    
    for (int i = 0; i < nRows; ++i) {
        for (int j = 0; j < nCols; ++j) {
            arr[i][j] = tree[i][j];
        }
    }
    
    reprVectorsTree *r1 = new reprVectorsTree(arr, nRows, nCols);
    

    【讨论】:

    • 不,这根本不起作用,float**float[][] 是不同种类的动物。
    • 好的,同意你的看法!我只是以为他想将二维数组传递给函数。将纠正我的答案。
    • float** 是指向float 的指针。您不能使用声明为 float[n][m] 的矩阵调用您的 reprVectorsTree 版本,它们具有完全不同的内存布局。
    • 是的,是的。这个问题被误解了。
    猜你喜欢
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 2012-04-27
    • 2020-12-09
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多