Перейти к содержимому

Как вернуть двумерный массив из функции c

  • автор:

Как в С возвратить массив из функции?

Если на минутку исключить из рассмотрения трюк с заворачиванием массива в struct , то в языке С невозможно буквально вернуть массив из функции (или передать массив в функцию). Массивы в С являются некопируемыми объектами — их нельзя никуда «передать» и ниоткуда «вернуть». Передавать или возвращать вы можете только указатели на массивы (на сами массивы или на их элементы).

По этой причине когда говорят о «возвращении массива из функции» в контексте языка С обычно понимают следующие варианты:

    Возвращение указателя на массив (на начало массива). Возвращаемый указатель не может указывать на автоматический массив, объявленный внутри этой функции, так как такой массив будет уничтожен при выходе из функции.
    Возвращаемый указатель может указывать на динамически выделенную память

char *bool_input(void) < char *result = malloc(/* размер */); /* Заполнение массива */ return result; >
char *bool_input(void) < static char result[/* размер */]; /* Заполнение массива */ return result; >
void bool_input(char result[], size_t size) < /* Заполнение массива */ >

Если вам так больше нравится, вы можете сделать и так

char *bool_input(char result[], size_t size) < /* Заполнение массива */ return result; >
struct Point < int xyz[3]; >; struct Point point_123(void) < return (struct Point) < < 1, 2, 3 >>; > 

Основным вариантом «возвращения массивов» в языке С является именно вариант номер 2. А вариант 1 при желании можно реализовать в виде надстройки над вариантом 2.

вернуть указатель на двумерный массив

Здравствуйте уважаемые сишники. Имеется несколько статических двумерных массивов, все M x N. Как записать тип функции, которая вернет указатель на один из этих массивов? Очень не хочется переделывать на char**.

Aswed ★★★★★
18.02.14 22:53:09 MSK

Ctrl+A Backspace Ctrl+S Alt+F4

templarrr ★★★★★
( 18.02.14 22:55:04 MSK )

которая вернет указатель на один из этих массивов?

Может всё-таки на первый элемент?

ziemin ★★
( 18.02.14 22:55:56 MSK )

static int v[M][N], u[M][N]; int (*f(void))[M][N]

Функция f возвращает указатель на двумерный массив.

anonymous
( 18.02.14 23:03:45 MSK )
Ответ на: комментарий от anonymous 18.02.14 23:03:45 MSK
Aswed ★★★★★
( 18.02.14 23:11:03 MSK ) автор топика

в Сях(«обычных») не гарантируется проверка выхода за границу массива и даже ожидается , что таковой нет во строенных синтаксических конструкциях.

то, что нарисовал анонимус лиш «коментарий» чека на проверку что это именно прямоугольный MxN , а не вектор M*Nx1 , а не вектор 1*M*N, а ли ещё какой вариант прямоуголизации числа MxN «обычный С-компилятор» делать не обязан и как правило таковы реализации.

вообщем хоть и стёб но Брайан Керниганом:

«Почему Паскаль не является моим любимым языком программирования»

ща (да и в большинстве и тогда) эта статья не о Паскалях , а о некоторых чертах С которые должны быть в языках — и там особо подчёркивается , что не должа компилятором функция работающая с однородными наборами (ака вектора ака массивы) ограничиватся константными размерами(формами) ибо наличие таковой черты в языке убыточно для программиста-пользователя этого языка.

qulinxao ★★☆
( 19.02.14 08:55:52 MSK )

Имеется несколько статических двумерных массивов, все M x N.

в PureC не бывает многомерных массивов. Бывают массивы массивов. Ты про них?

если да, то у меня для тебя плохие новости: невозможно вернуть массив изх функции. Можно только указатель.

только так можно:

#include void print_matrix(int matrix[][3]) < int j, k; for(j = 0; j < 3; j++, printf("\n")) for(k = 0; k < 3; k++) printf("%d ", matrix[j][k]); >void gen_matrix1(int matrix[][3]) < int j, k; for(j = 0; j < 3; j++) for(k = 0; k < 3; k++) matrix[j][k] = (j==k ? 1 : 0); >int main()

как вернуть двухмерный масив из функции)?

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

06 сентября 2006 года
278 / / 17.06.2006
Его нужно создать динамически:
Можно так:
int** b = new int*[N];
for(int i = 0; i < N; i ++)
b = new int[M];

И возвращать указатель
10 сентября 2006 года
77 / / 10.09.2006

Не обязательно. Вот статья:

Массив как передаваемый параметр.

Массив в качестве параметра может быть передан в функцию только с помощью указателя (адреса) массива. В качестве формального параметра массива данных любого типа можно использовать
1) имя массива с фиксированными границами, например
int a[10] , float b[2][3];
2) указателя на начало массива , например
int *a , float **b;
Фактическим параметром может быть имя массива — адрес начала массива в ОП или имя указателя на данные того же типа. Необходимо помнить о выделении памяти при работе с динамическими массивами. В связи с тем, что при работе с массивами фактическим параметром является адрес начала массива , обработка массива в вызванной функции производится над данными , расположенными в ОП , выделенной массиву вызывающей функции . При этом все изменения массива в вызванной функции сохраняются в массиве вызывающей функции.
Пример: ввести элементы массива и распечатать их.
Для решения этой задачи объявляем массив, передаём его функции, которая его заполняет и выйдя из этой функции распечатываем его.
#include
void vvod(int a[3][4]); // объявление функции vvod с массивом в
// качестве формального параметра
void main() // тело функция main
int b[3][4] , i, k;
vvod(b); // вызов функции vvod
for(i = 0;i <3;i++) // распечатка элементов массива b
< printf(“\n”);
for(k=0;k <4;k++)
printf(“ %d”,b[k]);
>
>
>

Все вышеприведенное справедливо для с++ 3.1. Правда, работая в среде visual studio 2005 я никаких несовместимостей не заметил.

Как вернуть указатель на двухмерный массив?

У меня падает исключение при попытке получить доступ к элементу, хотя я проверяю всё на nullptr и указатель не нулевой, нулевым он становится только при попытке доступа к элементу.

  • Вопрос задан более трёх лет назад
  • 1403 просмотра

1 комментарий

Простой 1 комментарий

Евгений Шатунов @MarkusD Куратор тега C++

Герман , N-мерные массивы статической длины не являются N-мерными в полном смысле этого слова.
По факту, грубо говоря, в своей функции ты делаешь каст памяти с данными типа bool* к типу bool** .
Очевидно, что твои булевы данные теперь трактуются как адреса на какие-то булевы данные.

Ты лучше просто переходи на составные типы данных. Структуру там оформи или нормальный класс с нормальным соответствием SOLID.

Решения вопроса 1
Программист на «си с крестами» и не только

typedef bool SymbolBoolMap[16][15]; static SymbolBoolMap symbol_Bool_Map_English_Upper_A = < . >;

и возвращай [const] SymbolBoolMap& .

Вообще есть два разных метода организации многомерных массивов: кусок памяти M×N и одномерный массив[M] указателей на массивы[N].
Если для одномерных массивов кусок памяти длины N впрямую конвертируется в указатель (и даже при определённых условиях всё работает), то в многомерных первое и второе НЕСОВМЕСТИМЫ.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *