Этот вопрос закрыт для ответов, так как повторяет вопрос Как передать двухмерный массив в метод класса с++?
Demigodd
@Demigodd

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

spoiler
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int size = 5;
int sum;

int prn(int sum) {
	std::cout << " = " << sum << "\n";
}

void foo(int arr[][size]) {
        int i = 0;
        while(i < size) {
            sum += arr[i][i];
            i++;
        }
        std::cout << "array:";
        prn(sum);
}

int main() {
    srand(time(NULL));
    
    std::cout << "Write the Length of the Array: ";
    std::cin >> size;
    
    int arr[size][size] = {};
    
     for(int i = 0; i < size; i++) {
            for(int j = 0; j < size; j++) {
                arr[i][j] = rand() % 10;
            }
        }
        
    foo(arr);
}

Если запустить так то будет ошибка.

но если указать вместо size, конкретную цифру то все сработает.

void foo(int arr[][5]) { ... }

int arr[5][5] = {};


Как в первом случае отправить массив в функцию ? Подскажите самый оптимальный вариант.
  • Вопрос задан
  • 10381 просмотр
Решения вопроса 3
myjcom
@myjcom Куратор тега C++
const int size
Массив не передается. Передается указатель. Даже если вы пишете a[][size]
Ответ написан
@Ariox41
Можно так:

#include <array>

template<std::size_t ColumnCount, std::size_t RowCount > 
int foo(int (&matrix)[ColumnCount][RowCount]){ 
   int r = 0;
   for(auto& row: matrix){
       for(auto& x: row)
          r += x;
   }
   return r;
}

int bar(){
    int matrix [][2] = {{1, 2}, {3, 4}, {4, 6}};
    return foo(matrix);
}


С-массивы в функции можно передавать только по ссылке. Или преобразовать в массив указателей.

Вообще, для передачи С-массивов придуман std::array, но двумерный C-массив нельзя напрямую привести к std::array<std::array<int, M>, N>. Но можно изначально работать с std::array:
template<std::size_t ColumnCount, std::size_t RowCount > 

int foo(std::array<std::array<int, RowCount>, ColumnCount>& matrix){ 
   int r = 0;
   for(auto& row: matrix){
       for(auto& x: row)
          r += x;
   }
   return r;
}

int bar(){
    std::array<std::array<int, 2>, 3> matrix = {{{1, 2}, {3, 4}, {4, 6}}};
    return foo(matrix);
}
Ответ написан
@res2001
Developer, ex-admin
Если вы изучаете С++, то лучше использовать классы стандартной библиотеки для массивов. В функцию передаете ссылку на класс.
В чистом Си передается просто указатель и размер в отдельном параметре (или 2 размера для двумерного массива).
Сам двумерный массив может быть представлен в двух вариантах:
1.Как массив указателей, где каждый указатель представляет собой одномерный массив. Нужно отдельно выделять память для массива указателей и для каждого одномерного подмассива и аналогично освобождать. В этом случае возможна операция индексации обоих измерений массива, при этом массив указателей и каждый подмассив могут находится в разных участках памяти.
void foo(int ** arr, int N, int M)
{
...
}
int main()
{
  int N = 10; // первое измерение массива
  int M = 20; // второе измерение массива
  int ** arr = new int * [N];
  for(int i = 0; i < M; ++i)
  {
     arr[i] = new int[M];
  }
  ...
  foo(arr, N, M);
  ...
  // Тут освобождение массива аналогично выделению в обратном порядке
}

2.Как одномерный массив размерностью N * M. В этом случае память под массив выделяется и освобождается вся оптом одним куском, но операция индексации первых размерностей не возможна. Но можно легко переходить от двумерного массива к одномерному, сразу вычислять нужный индекс или просто перемещаться по элементам массива с помощью временного указателя.
void foo(int * arr, size_t N, size_t M) 
{
  ...
}
int main()
{
  int N = 10; // первое измерение массива
  int M = 20; // второе измерение массива
  int * arr = new int * [N*M];
  int * arrcur = arr;  // временный указатель для обхода массива
  int * arrone = arr;  // вариант с переходом к одномерному массиву
  for(int i = 0; i < N; ++i)
  {
    for(int j = 0; j < M; ++j)
    {
        // Вариант с вычислением адреса текущего элемента по индексам
       *(arr + i * M + j) = rand() % 10;   // вычисление нужного индекса на месте
       // Вариант с обходом массива с помощью временного указателя
       *arrcur = rand() % 10; 
       ++arrcur;  // переход к следующему элементу
       // Вариант с переходом к одномерному массиву
      arrone[j] = rand() % 10; 
    }
    arrone += M;
  }
  ...
  foo(arr, N, M);
  ...
  delete[] arr;
}
Ответ написан
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы