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

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

  • автор:

Передача массива в функцию и возврат из функции

Особенность передачи массивов в функции в языке Си в том, что передается не сам массив, а адрес массива, который хранится в локальном указателе на него.

Это можно сделать по-разному, но результат будет одинаковый:

  • void some_function(int array[]);
  • void some_function(int *array);

При этом обязательно нужно указать тип элемента массива.

Размер массива в функцию автоматически не передается, поэтому если размер массива заранее (на этапе компиляции) не оговорен, то нужно передать параметр, который содержит количество элементов в массиве, например number_of_elements:

void some_function(int array[], int number_of_elements);

Следующая программа передает массивы в функцию show_array, которая использует цикл for для вывода значений массивов:

show_array.c

void show_array (int array [], int number_of_elements)
for ( int i = 0; i < number_of_elements; i++) printf("%d\t", array[i]);
>
printf(«\n»);
>

int main()
int little_numbers[5] = ;
int big_numbers[3] = ;
show_array(little_numbers, 5);
show_array(big_numbers, 3);
>

Массив просто передается в функцию по имени (а его имя — это адрес первого элемента), а также указывает параметр, который сообщает функции количество элементов, содержащихся в массиве:

Изменение массива из функции

Возможно ли поменять значения элементов из функции?

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

Следующая программа использует функцию get_values, чтобы присвоить три значения массиву numbers:

values_from_keyboard.c

#include
void read_array(int array[], int number_of_elements)
for(int i = 0; i < number_of_elements; i++)
printf(«Введите значение №%d: «, i);
scanf(«%d», &array[i]);
>
>

int main()
int numbers[3] = ;
read_array (numbers, 3); //массив будет изменен!
printf(» Значения массива\n»);
for (int i = 0; i < 3; i++) printf(" numbers [%d] \n", i);
>

Как видите, программа передает массив в функцию по имени, а функция присваивает массиву элементы.

Таким образом, функция может изменить элементы массива, если ей это нужно.

возврат массива из фу-ии Си

Здравствуйте! Можно ли сделать так на Си: int mas[2]; mas = func(); чтобы функция возвратила массив из двух целых. Если можно, то как описать данную функцию? Зарание спасибо!

anonymous
31.01.06 00:31:27 MSK

функции в си не умеет возвращать массивы. открывай учебник и кури главу «указатели»

friday ★★★
( 31.01.06 01:05:15 MSK )

можно массив обернуть в структуру. Старый Си не умел возвращать структуры, новый умеет.

dilmah ★★★★★
( 31.01.06 01:20:51 MSK )
Ответ на: комментарий от dilmah 31.01.06 01:20:51 MSK

А не проще указатель на память вернуть? Естественно, не на стек функции 🙂

anonymous_incognito ★★★★★
( 01.02.06 01:00:57 MSK )

Можно в качестве аргумента указать массив, а он передается как указатель, вот его и использовать.

stassats ★★★★
( 01.02.06 03:39:32 MSK )
Может пойдет? Почти похоже. #include int * f()< int a[2]=; int *p=a; return p; > int main()
vikeng
( 01.02.06 09:11:03 MSK )
Ответ на: комментарий от vikeng 01.02.06 09:11:03 MSK

А ничего, что f() возвращает адресс локальной переменной?

frenzy
( 01.02.06 10:44:58 MSK )
Ответ на: комментарий от frenzy 01.02.06 10:44:58 MSK

Ничего. Программа рабочая, все компилируется и работает.

vikeng
( 01.02.06 18:50:05 MSK )
Ответ на: комментарий от vikeng 01.02.06 18:50:05 MSK
vikeng: Нельзя так делать! > Программа рабочая, все компилируется и работает. А ты еще чего-нибудь вызови, она и перестанет работать. Например, попробуй такое у себя прогнать: #include #include int * f()< int a[2]=; int *p=a; return p; > int main()
Die-Hard ★★★★★
( 01.02.06 19:19:39 MSK )
Ответ на: комментарий от vikeng 01.02.06 18:50:05 MSK

> Ничего. Программа рабочая, все компилируется и работает.

Ёлки-палки, я в шутку предостерёг от выдачи адреса локальной переменной на стеке, а ты мало того что так сделал, ещё и полагаешь нормальным.

1)Локальная переменная размещается в стеке функции, т.е. в области памяти, закреплённой за функцией _только_ на время её вызова.

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

3)Правильно будет, использовать функцию выделения памяти в куче (malloc, calloc, new, ещё что-нибудь) и работать с ней.

anonymous_incognito ★★★★★
( 01.02.06 20:54:48 MSK )
Ответ на: комментарий от anonymous_incognito 01.02.06 20:54:48 MSK

Не знал. Спасибо, что объяснили. А я-то думал, что если работает, то и проблем нет. 🙂

vikeng
( 02.02.06 08:39:01 MSK )

Вроде в чистом С нет разницы между указателями и массивами но возвратить из функции можно только ссылку на глобальный объект или указатель на память выделенную внутри тела функции

anonymous
( 02.02.06 09:21:45 MSK )
Ответ на: комментарий от anonymous 02.02.06 09:21:45 MSK

>Вроде в чистом С нет разницы между указателями и массивами

небольшая всётаки есть: например их по разному понимает sizeof()

C# вернуть массив из функции

vedro-compota's picture

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

double []

Как известно — возвращаемый тип указывается перед именем функции (но после области видимости) — если ничего не возращают, то используют ключевое слово void

Key Words for FKN + antitotal forum (CS VSU):

  • неофициальный форум фкн
  • ФКН ВГУ Воронеж
  • программирование Воронеж
  • ВГУ информатика
  • ВГУ компьютерных наук
  • сайт студента
  • программирование информатика IT
  • сайт о программировании
  • примеры программного кода
  • сообщество программистов
  • Log in to post comments
  • 34630 reads

baton's picture

Wed, 01/15/2014 — 21:55

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

Я знаю что во всех почти других языка есть такой тип метода как int[] и я могу вернуть, массив который я передал. Вот есть такой код:

int A[3] = ; int Func(int Array[]) < for(i = 0; i < 3; i++)< Array[i] =+1; >return Array; > 

Как такое сделать?
Отслеживать
23.8k 3 3 золотых знака 47 47 серебряных знаков 62 62 бронзовых знака
задан 22 мая 2016 в 19:40
user211131 user211131
57 1 1 золотой знак 1 1 серебряный знак 2 2 бронзовых знака

Вы бы книжку прочитали. В С++ вместо массивов обычно используется std::vector . Ну или int* , если хочется посложнее.

22 мая 2016 в 19:45
А можете показать пример с указателями ?
22 мая 2016 в 19:47

Int * array; динамическая переменная. Под неё можешь выделить сколько тебе нужно памяти. array = new int[10]. Возвращаешь как обычный указатель.

22 мая 2016 в 20:05
Если вам дан исчерпывающий ответ, отметьте его как верный (галка напротив выбранного ответа).
23 мая 2016 в 7:03

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Дело в том что в C++ в функцию можно передать только указатель (или ссылку) на массив, соответственно вы всегда будете работать с исходным массивом, а не с его копией (и вернете также указатель на исходный массив):

int* Func(int *Array) < for(i = 0; i < 3; i++) < Array[i]++; >return Array; > 

Так же этот код не учитывает размер массива (цикл проходит строго три раза), что может привести к следующему:

  • если длина входного массива больше 3: обработаны будут только первые три элемента массива;
  • если длина входного массива меньше 3: программа упадет с грохотом и ошибкой доступа к памяти.

Проблему с размером можно решить двумя путями: передавать в функцию дополнительно размер массива или передавать массив по ссылке (если передавать массив по ссылке, ошибки с тем, что вы передали или вернули массив неправильного размера будут выявлены на стадии компиляции):

int* Func(int* Array, int size) // передача размера, тогда цикл будет for (int i = 0; i < size; i++) int (& Func(int (&Array)[3]))[3] // передача по ссылке, тогда цикл будет for (int i = 0; i < 3; i++) 

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

Чтобы вернуть новый массив, придется просто внутри функции выделить память под новый массив и вернуть указатель на нее (главное потом не забыть очистить память):

int* Func(int* Array, int size) < int *new_array = new int[size]; for(int i = 0; i < size; i++) < new_array[i] = Array[i] + 1; >return new_array; > 

Но у нас же C++, черт возьми, так что стоит вместо стандартных сишных массивов воспользоваться теми контейнерами, которые предоставляет Родина STL:

  • std::vector такой "массив" с изменяемым размером;
  • std::array массив фиксированного размера.

Теперь мы можем использовать итераторы, Range-based for loop (начиная с C++11) и прочие прелести:

std::vector Func(std::vector Array) // пример с vector и циклом со счетчиком < for (int i = 0; i < Array.size(); i++) < Array[i]++; >std::array Func(std::array Array) // с array и крутым циклом с итераторами < for (std::array::iterator it = Array.begin(); it < Array.end(); it++) < *i++; >return Array; > 

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

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