【问题标题】:How to pass two dimensional array of an unknown size to a function如何将未知大小的二维数组传递给函数
【发布时间】:2012-04-27 04:49:09
【问题描述】:

我想制作一个类库,一个函数,它的参数是一个未知大小的矩阵,用户将创建自己的大小自己的矩阵,并将其传递给这个函数,对他的矩阵做一些操作,如下所示,将是函数

calculateDeterminantOfTheMatrix( int matrix[][])
{
   some Operations to do on matrix 
}

【问题讨论】:

  • int** 矩阵将是您正在寻找的语法。
  • 如果你要让人们传递任意大小的矩阵,让他们也传递行数和列数。或者,或者,使用std::vector<std::vector<int>>
  • @SteveHoward 二维数组不会衰减为指向 C++ 中指针的指针。
  • 你可以使用boost/multiarray

标签: c++ function pointers matrix


【解决方案1】:

C 和 C++ 的内置组件不太支持多维数组。只有在编译时知道N-1 维度时,才能传递N-dimension 数组:

calculateDeterminantOfTheMatrix( int matrix[][123])

但是,标准库提供了 std::vector 容器,该容器非常适用于多维数组:在您的情况下,传递 vector<vector<int> > &matrix 将是在 C++ 中处理任务的正确方法。

int calculateDeterminantOfTheMatrix(vector<vector<int> > &matrix) {
    int res = 0;
    for (int i = 0 ; i != matrix.size() ; i++)
        for(int j = 0 ; j != matrix[i].size() ; j++)
            res += matrix[i][j];
    return res;
}

另外,您不需要将矩阵的维度传递给函数:matrix.size() 代表第一个维度,matrix[0].size() 代表第二个维度。

【讨论】:

  • 如果我声明它calculateDeterminantOfTheMatrix(vector&lt;vector&lt;int&gt; &gt; &amp;matrix),我将能够像这样循环它for(matrix[rowNumber][columnNumber]
  • @AhmedZainElDein 我添加了一个循环矩阵元素的示例,以防您传入vector&lt;vector&lt;int&gt; &gt;
  • @AhmedZainElDein 你可以让它工作,但要困难得多:你需要以不同的方式分配它,在单独的参数中传递大小,并在完成后释放所有内容。
  • @AhmedZainElDein 这是一个link 答案,它显示了指针技术的指针。
  • 请注意,对于向量向量,每次访问都会花费 3 次指针取消引用,而不是使用二维数组(当然,在运行时已知维度)。您取消引用外部向量以找到指向向量内存的指针,您取消引用以访问内部向量,然后取消引用以找到您正在寻找的实际整数。传统上它只需要一次乘法和一次取消引用。
【解决方案2】:

C 解决方案:

在 C 中,作为函数参数传递时,您不能省略数组大小(最左边除外)。

你可以写: 一个[]

但不能: 整数 [][]

例如: int a[][20]

这里有这个约束,因为编译器需要确定访问数组元素的正确偏移量。但是,您可以这样做:

void print_arbitrary_2D_array(void *arr, int y, int x)
{
    /* cast to 2D array type */
    double (*p_arr)[y][x] = (double (*)[y][x]) arr;

    int i, j;

    for (i = 0; i < y; ++i) {
        for (j = 0; j < x; ++j)
            printf(" %lf", (*p_arr)[i][j]);
        putchar('\n');
    }
}

double arr_1[4][3] = {
    { 3.3, 5.8, 2.3 },
    { 9.1, 3.2, 6.1 },
    { 1.2, 7.9, 9.4 },
    { 0.2, 9.5, 2.4 }
};
double arr_2[2][5] = {
    { 3.6, 1.4, 6.7, 0.1, 4.2 },
    { 8.4, 2.3, 5.9, 1.4, 8.3 }
};

print_arbitrary_2D_array(arr_1, 4, 3);
putchar('\n');
print_arbitrary_2D_array(arr_2, 2, 5);

【讨论】:

  • int (*q)[m][n]=( int(*)[m][n])p; 此转换在 Clion 中不起作用。这int (*q)[n]=( int(*)[n])p;
【解决方案3】:

您可以采取多种方法。

  1. C 做事方式 -> 传入int**,但在这里要格外小心。这不是一个二维数组。您必须正确地为该指针分配内存,或者,您需要在编译时知道大小。 (例如,静态分配一个大小为 M * N 的数组,然后禁止任何更大的数组)。为了动态分配内存,需要知道行数和列数。

  2. C++ 方式 -> #include &lt;vector&gt; 之后您可以简单地使用 vector&lt;vector&lt;int&gt; &gt; &amp;matrix (注意&lt;int&gt; 后面的空格,除非您使用的是 c++11 编译器。),这将分配一个向量基本上是一个二维数组的 int 向量。在这种情况下,内存管理将为您处理。

【讨论】:

  • 考虑到二维数组可以按行或按列存储时,C 的处理方式也会变得复杂。
【解决方案4】:

我会为定义了列和行的矩阵编写一个简单的类包装器。

template <typename T>
class Mat {
  std::size_t _row;
  std::size_t _col;

  T *_mat_elem;
public:
  Mat(std::size_t r, std::size_t c)
   :  _row(r), _col(c), _mat_elem(new T[r*c] {}
  ~Mat() {/* remember to do delete [] here */}

  // element access, for example
  T& at(std::size_t r, std::size_t c)
  {
    return *(_mat_elem+r*_col+c);
  }
};

但实际上你是在重新发明轮子。那里有很好的矩阵处理库。

【讨论】:

  • 这是一个比其他两个更好的答案。
【解决方案5】:

使用这个方法 声明一个指针数组 例如:int *a[n]; 然后使用 for 循环为它们分配内存 例如:

for( int i=0 ; i<n ; i++ )
        a[i] = new int[n];

现在像普通数组一样传递参数。 例如: print_array(a,n); 而 print_array 函数看起来像

print_array(int **a,int n)//the prototype for the print_array
{
 //access the array using index such as
std:: cout<<a[1][1]<<endl;
}

上述情况适用于 nxn 数组,如果需要 mxn 则 像这样分配内存

for( int i=0 ; i<m ; i++ )
        a[i] = new int[n];

然后将 m,n 和传递给函数并在 for 循环中访问数组。

【讨论】:

    【解决方案6】:

    到目前为止,在我发现的函数中使用二维数组的最佳方法是使用映射函数。如下例所示,我使用了映射函数来打印二维数组

    void Print2D(int x[],int ROWS,int COLS)
    {
        for(int i=0;i<ROWS;i++)
    {
        for(int j=0;j<COLS;j++)
        cout << x[i*COLS+j] << ' ';
        cout << endl;
    
    }
    }
    

    这是如何在main中使用它

    int main(){
    
        int x[3][3];
        Print2D(&x[0],3,3);
    
    }
    

    这里&x[0]是二维数组第一行的起始地址或更准确地说是二维数组的起始地址

    【讨论】:

      猜你喜欢
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 2011-05-24
      • 2011-08-20
      • 2017-11-22
      • 2020-11-01
      相关资源
      最近更新 更多