Как передать двумерный массив неизвестного размера функции
Я хочу создать библиотеку классов, функцию, которую его параметр представляет собой матрицу неизвестного размера, и пользователь создаст свою собственную матрицу со своим размером и передаст ее этой функции, чтобы выполнить некоторые операции над своей матрицей, будет функцией
calculateDeterminantOfTheMatrix( int matrix[][])
{
some Operations to do on matrix
}
Ответы
Ответ 1
Многомерные массивы не очень хорошо поддерживаются встроенными компонентами C и С++. Вы можете передать массив N
-dimension только тогда, когда вы знаете измерения N-1
во время компиляции:
calculateDeterminantOfTheMatrix( int matrix[][123])
Однако стандартная библиотека предоставляет контейнер std::vector
, который отлично подходит для многомерных массивов: в вашем случае передача vector<vector<int> > &matrix
будет правильным способом справиться с задачей на С++.
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()
представляет второе измерение.
Ответ 2
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);
Ответ 3
Существует несколько подходов, которые вы могли бы предпринять.
-
C способ делать вещи → Переходите в int**
, но будьте предельно осторожны. Это не совсем 2D-массив. Вам нужно будет правильно выделить память этому указателю или, наоборот, вам нужно знать размер во время компиляции. (Например, статически распределяя массив размера M * N, а затем запрещая что-либо большее). Чтобы динамически распределять память, вам нужно знать количество строк и столбцов.
-
С++ way → #include <vector>
, после которого вы можете просто использовать vector<vector<int> > &matrix
(Осторожно про место после <int>
, если вы не используете компилятор С++ 11), который будет выделять вектор из int-векторов, который в основном представляет собой 2d-массив. В этом случае управление памятью будет заботиться о вас.
Ответ 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
используйте этот метод для объявления массива указателей ex: 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
Лучший способ использовать 2D-массив в функции, которую я нашел до сих пор, это использовать функцию отображения. Как и в примере ниже, я использовал функцию отображения для печати 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;
}
}
Вот как это использовать в основном
int main(){
int x[3][3];
Print2D(&x[0],3,3);
}
Здесь & x [0] - начальный адрес первой строки двумерного массива или, точнее, начальный адрес двумерного массива.