Как передать функции двумерный массив неизвестного размера

Я хочу сделать библиотеку классов функцией, параметр которой является матрицей неизвестного размера, и пользователь создаст свою собственную матрицу с собственным размером и передаст ее этой функции для выполнения некоторых операций над своей матрицей, как это, будет функция

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

4 ответов


многомерные массивы не очень хорошо поддерживаются встроенными компонентами C и c++. Вы можете пройти N-размерный массив только тогда, когда вы знаете N-1 размеры во время компиляции:

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() - это второе измерение.


C решение:

В C вы не можете опустить размер массива (кроме левого) при передаче в качестве параметра функции.

вы можете писать: int a[]

но не могу: int a[][]

например: 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);

есть несколько подходов, которые вы могли бы принять.

  1. C способ делать вещи - > пройти в int** но будьте предельно осторожны здесь. Это не совсем 2D массив. Вам нужно будет правильно выделить память этому указателю, или, альтернативно, вам нужно знать размер во время компиляции. (Например, статически выделяя массив размера M * N, а затем запрещая что-либо большее). Чтобы динамически распределять память, необходимо знать количество строк и колонны.

  2. в C++ способ -> #include <vector> после чего вы можете просто использовать vector<vector<int> > &matrix (осторожно о пространстве после <int> Если вы используете компилятор C++11.), который выделит вектор векторов int, который в основном является 2d-массивом. Управление памятью будет позаботиться о вас в этом случае.


Я бы написал простую оболочку класса для матрицы с определенными столбцом и строкой.

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

но на самом деле вы не изобретая колеса. Есть хорошие библиотеки для обработки матриц.