как передать двумерный масив в функцию?

как передать двумерный масив в функцию чтобы так работало?

int massiv[5][7];

functia(massiv, 5, 7);

Ответы (5 шт):

Автор решения: Harry

Например, так:

#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] уже не получится - придется самостоятельно с индексами работать...

→ Ссылка
Автор решения: user7860670

Если необходима работа именно с массивом массивов, то имеет смыл передавать по ссылке. Это также избавить от необходимости дополнительно передавать его размеры:

using t_Massiv = int[5][7];
functia(t_Massiv & massiv);

t_Massiv massiv{};
functia(massiv);
→ Ссылка
Автор решения: AR Hovsepyan

Каждый двумерный массив имеет свой тип. 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.

→ Ссылка
Автор решения: EOF

Сразу скажу, что этот способ лучше не использовать. Следующая возможность есть в С, но некоторые С++ компиляторы поддерживают её. Почти всегда лучше использовать контейнеры из 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;
}
→ Ссылка
Автор решения: AlexGlebe

Стандарт запрещает передавать как аргумент указатель на массив неизвестных размеров. Можно передавать указатель как 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
→ Ссылка