简体   繁体   English

如何将未知大小的二维数组传递给函数

[英]How to pass two dimensional array of an unknown size to a function

I want to make class library, a function which its parameter is a matrix of unknown size, and the user will create his own matrix with his own size and pass it to this function to do some operations on his matrix like this, will be the function 我想创建类库,一个函数,其参数是一个未知大小的矩阵,用户将创建自己的矩阵,并使用自己的大小并将其传递给此函数,对其矩阵进行如下操作,将是功能

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

Multi-dimensional arrays are not very well supported by the built-in components of C and C++. C和C ++的内置组件不能很好地支持多维数组。 You can pass an N -dimension array only when you know N-1 dimensions at compile time: 只有在编译时知道N-1维度时,才能传递N维数组:

calculateDeterminantOfTheMatrix( int matrix[][123])

However, the standard library supplies std::vector container, that works very well for multi-dimension arrays: in your case, passing vector<vector<int> > &matrix would be the proper way of dealing with the task in C++. 但是,标准库提供了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;
}

As an added bonus, you wouldn't need to pass dimensions of the matrix to the function: matrix.size() represents the first dimension, and matrix[0].size() represents the second dimension. 作为额外的好处,您不需要将矩阵的维度传递给函数: matrix.size()表示第一维, matrix[0].size()表示第二维。

C solution: C解决方案:

In C you can't omit array size (except leftmost) when passing as function parameter. 在C中,当作为函数参数传递时,不能省略数组大小(除了最左边)。

You can write: int a[] 你可以写:int a []

but can't: int a[][] 但不能:int a [] []

just for example: int a[][20] 仅举例:int a [] [20]

This constraint is here, because compiler needs to determine proper offsets for accessing array elements. 此约束在此处,因为编译器需要确定用于访问数组元素的正确偏移量。 However, you can make it this way: 但是,你可以这样做:

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);

There are multiple approaches you could take. 您可以采取多种方法。

  1. C way of doing things -> Pass in a int** but be extremely cautious here. 做事的方式 - >传递int**但在这里要非常谨慎。 This is not quite a 2D array. 这不是一个二维数组。 You will have to correctly allocate memory to this pointer, or, alternatively, you need to know the size at compile time. 您必须正确地为此指针分配内存,或者,您需要在编译时知道大小。 (For instance staticly allocating an array of size M * N and then disallowing anything bigger). (例如,静态分配大小为M * N的数组,然后禁止任何更大的数组)。 In order to dynamically allocate the memory, you need to know the number of rows and columns. 为了动态分配内存,您需要知道行数和列数。

  2. C++ way -> #include <vector> after which you can simply use vector<vector<int> > &matrix (Careful about the space after the <int> unless you're using c++11 compiler.), which will allocate a vector of int vectors which is basically a 2d array. C ++方法 - > #include <vector>之后你可以简单地使用vector<vector<int> > &matrix (小心<int>之后的空格,除非你使用c ++ 11编译器。),这将分配一个int矢量的矢量,基本上是一个二维数组。 The memory management will be taken care of for you in this case. 在这种情况下,将为您处理内存管理。

I would write a simple class wrapper for the matrix with column and row defined. 我会为矩阵编写一个简单的类包装器,其中定义了列和行。

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);
  }
};

But actually you are re-inventing the wheels. 但实际上你正在重新发明轮子。 There are good libraries for matrix handling out there. 那里有很好的矩阵处理库。

use this method declare an array of pointers ex: int *a[n]; 使用此方法声明一个指针数组ex: int *a[n]; Then allocate memory for them using a for loop ex: 然后使用for循环ex为它们分配内存:

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

Now pass the argument like normal array. 现在像普通数组一样传递参数。 ex: print_array(a,n); 例如:print_array(a,n); And print_array function looks like 而且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;
}

The above case is for the array of nxn incase mxn is required then allocate the memory like 上面的例子是针对nxn的数组,需要mxn然后分配内存就好了

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

then pass the both m,n and to the function and access the array in the for loop. 然后将m,n传递给函数并访问for循环中的数组。

The Best way to use 2D array in the function that I have found so far is to use Mapping Function. 在我到目前为止找到的函数中使用2D数组的最佳方法是使用Mapping Function。 As in the example below , I have use the mapping function to print 2D array 如下例所示,我使用映射函数来打印2D数组

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;

}
}

Here it is how to use it in main 这是如何在main中使用它

int main(){

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

}

Here &x[0] is the starting address of the First Row of 2D array or more precisely Starting address of 2D array 这里&x [0]是2D阵列的第一行的起始地址,或者更准确地说是2D阵列的起始地址

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM