Сделать return массива

159
24 апреля 2019, 04:00

Не получается вернуть массив через функцию. Я создал функцию, которая создает массив и заполняет все его элементы двойками, но не могу вернуть ее через return
Вот сама функция

 int Create(int arr[20][20]){
 for (int i = 0; i < 20; i++) {
   for (int j=0; j<20; j++) {
        arr[i][j] = 2;
        }
    }
    return arr;
}  

Знаю что там можно как то через указатели, но у меня не получилось

Answer 1

Чтобы не париться с указателями на массивы (вектора) нужно обернуть матрицу структурой. Тогда можно принимать матрицу, зная её размер и возвращать также.

// g++ -Wall -Wextra -Wpedantic -Os retarr.cpp
# include <stdio.h>
# include <cstddef>
//# include <array> // c++11
template <typename T,std::size_t row,std::size_t col>
struct Matrix{
  T m[row][col];
} ;
template <typename T,std::size_t row,std::size_t col>
Matrix<T,row,col> & CreateM ( Matrix<T,row,col> & m ) {
  printf("CreateM.0.:m.m[5][10]=%d\n",m.m[5][10]);
  m.m[5][10] = 666 ;
  //...
  printf("CreateM.1.:m.m[5][10]=%d\n",m.m[5][10]);
  return m;  }
int main(){
  Matrix<int,10,20> m ;
  m.m[5][10]=777;
  printf("main:0.:m.m[5][10]=%d\n",m.m[5][10]);
  Matrix<int,10,20> & m2 = CreateM<int,10,20>(m);
  printf("main:1.:m2.m[5][10]=%d\n",m2.m[5][10]);
  }
Answer 2
auto Create(int arr[20][20]) -> int (*)[20]
{
  ...
  return arr;
}

или, если хотите

int (*Create(int arr[20][20]))[20]
{
  ...
  return arr;
}

(что то же самое).

Но большого смысла возвращать указатель на ваш массив нет - вы заполняете тот же самый массив, что и передавали снаружи. Он там снаружи и так у вас есть. Зачем его еще "возвращать"?

Answer 3

Во-первых в С++ нельзя принять (или вернуть) С-style массив по значению. Ваша функция имеет сигнатару int Create(int ( * arr )[20]), то бишь они принимает указатель на массив из 20 int, который создается в вызывающем коде, а не внутри функции. Соответственно имеет смысл принимать этот массив по ссылке, тогда компилятор будет проверять, что размер массива в вызывающем коде соответствует указанному и можно будет использовать range for:

void Fill(int ( & arr )[20][20], int const initial_value = 2)
{
    for(auto & row : arr)
    {
        for(auto & value : row)
        {
            value = initial_value;
        }
    }
    return;
}  
READ ALSO
Qt5 кроскомпиляция из под Windows в ARM

Qt5 кроскомпиляция из под Windows в ARM

Пытаюсь настроить Qt Creator (qt510

138
c++: выделение места под контейнер

c++: выделение места под контейнер

Подскажите пожалуйста, если у меня есть контейнер и я знаю сколько в нем примерно будет элементов, для ускорения работы я могу выделить их изначально,...

127
Как &ldquo;победить&rdquo; инкапсуляцию

Как “победить” инкапсуляцию

Обычный пример с юнитом

113