как передать двумерный масив в функцию?
как передать двумерный масив в функцию чтобы так работало?
int massiv[5][7];
functia(massiv, 5, 7);
Ответы (5 шт):
Например, так:
#include <vector>
#include <iostream>
using namespace std;
void functia(int *m, int d1, int d2)
{
for(int i = 0; i < d1; ++i)
{
for(int j = 0; j < d2; ++j)
cout << m[i*d2+j] << " ";
cout << endl;
}
}
int main()
{
int massiv[2][3] = { {1,2,3},{4,5,6}};
functia(&massiv[0][0], 2, 3);
// Ещеодин вариант - так:
functia((int*)massiv, 2, 3);
}
Только, как видите, обращаться как m[i][j] уже не получится - придется самостоятельно с индексами работать...
Если необходима работа именно с массивом массивов, то имеет смыл передавать по ссылке. Это также избавить от необходимости дополнительно передавать его размеры:
using t_Massiv = int[5][7];
functia(t_Massiv & massiv);
t_Massiv massiv{};
functia(massiv);
Каждый двумерный массив имеет свой тип.
int[row][4] имеет тип int(*)[4] или int[row][22] имеет тип int(*)[22], независимо от значения константного выражения row, поэтому, при передаче он все равно игнорируется, и нужно будет в функцию передать этот размер. Однако, передача любым таким способом, делает функцию не универсальной _ придется написать эту же функцию для массивов с различным количеством столбцов(количество элементов в строке). Более универсальные способы, это передать указатель на начало и две размерности(как указан в ответе Harry, и никакого UB не может иметь место), или же написать шаблонную функцию:
template<int row, int col>
void some_func(int(&arr)[row][col]);
Вот пример определения и использования такой функции:
template<int row, int col>
void some_func(int(&arr)[row][col]) {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
arr[i][j] = i + j;
std::cout << arr[i][j] << ' ';
}
std::cout << '\n';
}
}
int main() {
int A[3][4];
some_func(A);
return 0;
}
В функцию void functia(int *m, const int d1, const int d2) можно передать любой фрагмент двумерного массива, а также динамический массив, поэтому она более универсальна, но если код функции не тривиальна, нужно быть очень внимательным, дабы не допускать ошибок с индексами. Зато шаблонная относительно безопасна, хоть и не так универсальна. Можно без головной боли использовать C++ контейнеры: std::array, std::vector и т.д., элементами которых являются контейнеры фиксированного размера(количество столбцов) или std::valarray со срезами std::slice или std::gslice.
Сразу скажу, что этот способ лучше не использовать. Следующая возможность есть в С, но некоторые С++ компиляторы поддерживают её. Почти всегда лучше использовать контейнеры из STL. Но если вдруг Ваш компилятор поддерживает VLA, то можно писать так:
void functia(int rows, int cols, int arr[rows][cols])
{
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
cout << arr[row][col] << '\t';
}
cout << endl;
}
}
Вот пример использования:
int main()
{
int arr1[2][3] =
{
{1, 2, 3},
{4, 5, 6}
};
int arr2[5][5] =
{
{25, 24 ,23, 22, 21},
{20, 19, 18, 17, 16},
{15, 14, 13, 12, 11},
{10, 9, 8, 7, 6},
{ 5, 4, 3, 2, 1}
};
cout << "Arr1:\n";
functia(2, 3, arr1);
cout << "Arr2:\n";
functia(5, 5, arr2);
return 0;
}
Стандарт запрещает передавать как аргумент указатель на массив неизвестных размеров. Можно передавать указатель как int* а потом сменить на тип нужных размеров, но не все компиляторы это позволят. Выходом может послужить написание собственного класса.
// g++ -Wall -std=c++11 -Wextra -Wpedantic massarg.cpp -o massarg
# include <iostream>
void functia( int * pt,int l,int r){
// warning: ISO C++ forbids variable length array ‘m’ [-Wvla]
// стандарт запрещает массивы переменной длины
int (&m)[l][r] = *(int (*)[l][r])pt;
// m - это ссылка на массив указанных размеров
m[4][4] = 7 ; }
int massiv[5][7];
int massiv2[50][70];
class VArray {
public :
VArray(int,int);
~VArray();
int & Elt(int i ,int j){return pointer[i*rows+j];}
int Lines()const{return lines;}
int Rows()const{return rows;}
private :
int * pointer ;
int lines ;
int rows ;
} ;
VArray::VArray(int l,int r) {
lines = l ;
rows = r ;
pointer = new int [ size_t(l) * size_t(r) * sizeof(int) ] ; }
VArray::~VArray() {
delete [ ] pointer ; }
void functia2( VArray & arr ){
arr.Elt(4,4) = 7 ; }
int main(){
functia((int*)&massiv,5,7);
std::cout<<"massiv[4][4]="<<massiv[4][4]<<std::endl;
functia((int*)&massiv2,50,70);
std::cout<<"massiv2[4][4]="<<massiv2[4][4]<<std::endl;
VArray va (10,20);
functia2(va);
std::cout<<"va.Elt(4,4)="<<va.Elt(4,4)<<std::endl;
}
Результат при компиляции в g++ :
$ ./massarg
massiv[4][4]=7
massiv2[4][4]=7
va.Elt(4,4)=7