Задать вопрос
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] = {};


Как в первом случае отправить массив в функцию ? Подскажите самый оптимальный вариант.
  • Вопрос задан
  • 13691 просмотр
Подписаться 2 Средний
Решение пользователя res2001 К ответам на вопрос (3)
@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;
}
Ответ написан