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

Как вернуть два значения из функции c

  • автор:

вернуть Несколько значений из функции в C

Нужно возвратить из функции значения 2х переменных. На ум приходит только идея сделать массив с этими значениями и через return выдать указатель на него. Но может есть другой способ?

vdm ★★
28.12.06 05:20:13 MSK

Re: вернуть Несколько значений из функции в C

Не нравится мне твоё «сделать массив», сдаётся мне что ты собрался ссылку на локальный массив возвращать. 🙂 Очень не рекомендую. 🙂

Вообще обычно в таких случаях функции передают указатель на массив или структуру, в которую она пишет результаты. А возвращает она в таком случае просто код завершения (типа успешно/неуспешно). См., например, man 2 fstat.

Teak ★★★★★
( 28.12.06 05:25:30 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Teak 28.12.06 05:25:30 MSK

Re: вернуть Несколько значений из функции в C

typedef struct < int one, int two >retval2; retval2 * f(. ) < retval2 * retval = NULL; . if (!error) < retval = malloc(sizeof(retval2)); retval->one = one; retval->two = two; > return retval; > int main(. ) < retval2 * retval; if (retval = f(. )) < printf("one = %i, two = %i\n", retval->one, retval->two); free(retval); > > --- что нить типа такого в голову не приходило. )))

Ex ★★
( 28.12.06 09:01:16 MSK )

Re: вернуть Несколько значений из функции в C

> Нужно возвратить из функции значения 2х переменных. На ум приходит > только идея сделать массив с этими значениями и через return выдать > указатель на него. Но может есть другой способ? Так можно делать только если массив статический: int *foo() < static int a[] = ; return a; > Второй способ вернуть структуру: struct S foo(char c, double d) < struct S s; s.ch = c; s.dl = d; return s; >Третий способ, который обычно применяется во всех библиотеках, объявить массив или структуру во внешнем блоке и передавать в функцию их адреса.

shumer ★
( 28.12.06 09:40:31 MSK )

Re: вернуть Несколько значений из функции в C

Можно возвращать структуру, но считается, что это не оч. хорошо, т.к. вся структура укладывается в стек: typedef struct < int one; int two; >retval2; retval2 f() < retval2 x; x.one=1; x.two=2; return x; >int main(int argc, char **argv) < retval2 y; y=f(); >Выделять память внутри функции считается не оч. правильным путём, насколько я понимаю. Так что наиболее правильным является передача функции указателя на структуру (или массив): typedef struct < int one; int two; >retval2; int f(reval2 *x) < x->one=1; x->two=2; return 1; //код возврата=всё ок > int main(int argc, char **argv) < retval2 y; if (!f(&y)) //обработка ошибки >

Davidov ★★★★
( 28.12.06 10:17:07 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Davidov 28.12.06 10:17:07 MSK

Re: вернуть Несколько значений из функции в C

>> Выделять память внутри функции считается не оч. правильным путём, насколько я понимаю. Так что наиболее правильным является передача функции указателя на структуру (или массив):

не спорю, попросили привести пример, мну привел то что первое в голову пришло )

Ex ★★
( 28.12.06 10:49:02 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Ex 28.12.06 10:49:02 MSK

Re: вернуть Несколько значений из функции в C

>не спорю, попросили привести пример, мну привел то что первое в голову пришло )

Да не, никаких претензий. Сам так иногда делаю. Более того, по-моему, в каких-то стандартных вызовах было нечто подобное.

Я так понимаю, что логика состоит в том, что выделением памяти и её освобождением должны быть в логически эквивалентных местах.

То есть, например, в случае наличия функций retval2 *alloc_s1() и int free_s2(retval2 *r), всё уже хорошо. Вот и пример, где это может быть оправдано.

Кстати, всё это уже начинает смахивать на ООП.

Davidov ★★★★
( 28.12.06 10:57:57 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Davidov 28.12.06 10:57:57 MSK

Re: вернуть Несколько значений из функции в C

таки ООП это парадигма программирования и не зависит от конкретной реализации в ЯВУ

Ex ★★
( 28.12.06 11:05:00 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от shumer 28.12.06 09:40:31 MSK

Re: вернуть Несколько значений из функции в C

>Так можно делать только если массив статический: >int *foo() > < >static int a[] = ; > return a; >> Только надо быть очень аккуратным: при повторном вызове будет возвращён тот же указатель.

Davidov ★★★★
( 28.12.06 11:10:25 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Davidov 28.12.06 11:10:25 MSK

Re: вернуть Несколько значений из функции в C

>>Так можно делать только если массив статический:

>>int *foo() >>< >> static int a[] = ; >> return a; >>>

>Только надо быть очень аккуратным: при повторном вызове будет возвращён >тот же указатель.

Еще это несколько не thread-safe

anonymous
( 28.12.06 15:08:24 MSK )

Re: вернуть Несколько значений из функции в C

void test_retval (int a,int b, int c, int *ret1,int *ret2) < . *ret1=. ; *ret2=. ; >. int r1,r2 test_reatval(1,2,3,&r1,&r2); .

xnix ★★
( 28.12.06 16:25:14 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Ex 28.12.06 09:01:16 MSK

Re: вернуть Несколько значений из функции в C

Ну и нахрена звать malloc без необходимости? Если только чтоб выпендриться.

Teak ★★★★★
( 28.12.06 17:38:44 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от shumer 28.12.06 09:40:31 MSK

Re: вернуть Несколько значений из функции в C

> Так можно делать только если массив статический:

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

Teak ★★★★★
( 28.12.06 17:40:11 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Teak 28.12.06 17:40:11 MSK

Re: вернуть Несколько значений из функции в C

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

Конечно так делать не следует, хотя и возможно. Вобщем я сказал «can», а ты имел ввиду «may» 🙂

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

shumer ★
( 28.12.06 17:52:21 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от shumer 28.12.06 17:52:21 MSK

Re: вернуть Несколько значений из функции в C

Согласен, все посты в этой теме, кроме первого, моего, — лишние. 🙂

Teak ★★★★★
( 28.12.06 18:02:01 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Teak 28.12.06 17:38:44 MSK

Re: вернуть Несколько значений из функции в C

ув. тов. Teak прочтите пост выше.

Ex ★★
( 28.12.06 18:07:45 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Ex 28.12.06 18:07:45 MSK

Re: вернуть Несколько значений из функции в C

> ув. тов. Teak прочтите пост выше.

Не, Ex, извини, но ты там фигню написал. Заморачиваться со структурой в функции стоит только если ты ее всю будешь возращать (структурка небольшая). А создавать ее динамически, а потом возвращать указатель, имхо хреновая идея. Кто-то использующий твою функцию должен знать и помнить о том, что ему где-то free надо втыкать, лишний, тяжелый malloc, и ради чего все?

shumer ★
( 28.12.06 18:51:10 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от Teak 28.12.06 18:02:01 MSK

Re: вернуть Несколько значений из функции в C

> Согласен, все посты в этой теме, кроме первого, моего, — лишние. 🙂

ты не указал решение с возвратом структуры. Оно непопулярно, потому что этого не было в ранних компиляторах и про это не написано в К&Р Но для 2-х полей оно оптимально

dilmah ★★★★★
( 28.12.06 18:59:37 MSK )
Ответ на: Re: вернуть Несколько значений из функции в C от dilmah 28.12.06 18:59:37 MSK

Re: вернуть Несколько значений из функции в C

> Оно непопулярно, потому что этого не было в ранних компиляторах и про это не написано в К&Р

Вот хохма на эту тему, совершенно случайно наткнулся:

2.2: I heard that structures could be assigned to variables and passed to and from functions, but K&R I says not.

K&R I was wrong; they hadn’t actually learned C very well before writing the book. Later, Ritchie got a job at Bell Labs, and worked closely with the authors of C, allowing the 2nd edition of the book to be much more accurate. (Kernighan already worked at Bell Labs, as a video game developer.)

Как вернуть через функцию два значения в C++?

Суть : Допустим у нас есть функция, в результате выполнения действий внутри нее мы получаем значения переменных, которые нам необходимо вернуть. Как это сделать? И как при вызове присвоить эти значения двум переменным одновременно?

Отслеживать
218k 15 15 золотых знаков 117 117 серебряных знаков 229 229 бронзовых знаков
задан 11 дек 2017 в 15:55
Vlad Kvochin Vlad Kvochin
514 1 1 золотой знак 5 5 серебряных знаков 15 15 бронзовых знаков

Передать указатель на одно из возвращаемых значений и записать по нему. Второе — через return, например.

11 дек 2017 в 15:56
Как этим указателем воспользоваться вне функции, можно пример?
11 дек 2017 в 15:57
Читайте учебники про указатели и ссылки
11 дек 2017 в 15:58
Используйте structured binding.
11 дек 2017 в 16:00

2 ответа 2

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

  1. вернуть структуру или кортеж (пару) с двумя полями
  2. использовать передачу параметров по ссылке или через указатель.

Например, считать сумму и разность двух переменных:

std::pair sumdif(ina a, int b) < return pair(a+b,a-b); > void sumdif(int a, int b, int& sum, int& dif) < sum = a+b; dif = a-b; >. int a = 5, b = 7; auto p = sumdif(a,b); cout  
int a = 5, b = 7, s, d; sumdif(a,b,s,d); cout  

Дополнение через 3 года 🙂 - теперь можно использовать новый вариант синтаксиса структурного связывания:

std::pair sumdif(int a, int b) < return pair(a+b,a-b); > . int a = 5, b = 7; auto [s,d] = sumdif(a,b); cout  

Отслеживать
ответ дан 11 дек 2017 в 15:57
218k 15 15 золотых знаков 117 117 серебряных знаков 229 229 бронзовых знаков

Дополню ответ @Harry

Если под рукой компилятор с поддержкой 11 ого (и выше) стандарта, то можно воспользоваться std::tuple и вернуть его из функции, эдакое обобщение на std::pair для произвольноно числа элементов с разными типами

std::tuple f() < std::tuplet = < -1, 123 >; // . return t; > std::tuple g() < std::tuplet = < -1, false, 123 >; // . return t; > 

Отслеживать
ответ дан 11 дек 2017 в 18:59
3,681 1 1 золотой знак 17 17 серебряных знаков 31 31 бронзовый знак

  • c++
  • функции
  • структурное-связывание
    Важное на Мете
Связанные
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Возврат нескольких значений из функции в C

В этом посте будет обсуждаться, как вернуть несколько значений из функции в C.

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

1. Указатели в C

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

// Функция для возврата нескольких значений с помощью указателей
void initialize ( int * a , int * b , char * c )
// Возвращаем несколько значений из функции в C
int main ( void )
initialize ( & a , & b , & c ) ;
printf ( "a = %d, b = %d, c = %c" , a , b , c ) ;

результат:

a = 10, b = 20, c = A

2. Структуры в C

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

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

// обернуть несколько значений в структуру
struct Tuple < // Функция для возврата нескольких значений с использованием структуры struct Tuple initialize ( ) struct Tuple tuple = < 10 , 20 , 'A' >;
return tuple ;
// Возвращаем несколько значений из функции в C
int main ( void )
struct Tuple tuple = initialize ( ) ;
a = tuple . a ;
b = tuple . b ;
c = tuple . c ;
printf ( "a = %d, b = %d, c = %c" , a , b , c ) ;

результат:

a = 10, b = 20, c = A

3. Массив

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

// Функция для возврата нескольких значений с использованием массива
int * initialize ( )
// Важно: динамически выделять память
int * temp = ( int * ) malloc ( sizeof ( int ) * 3 ) ;
* ( temp + 1 ) = 20 ;
* ( temp + 2 ) = 30 ;
return temp ;
// Возвращаем несколько значений из функции в C
int main ( void )
int a , b , c ;
int * arr = initialize ( ) ;
printf ( "a = %d, b = %d, c = %d" , a , b , c ) ;
// свободная память

результат:

a = 10, b = 20, c = 30

Мы не должны использовать этот подход, так как информация о переменной не передается вызывающей функции. Например, мы используем индекс массива для получения значений наших переменных. Также обратите внимание, что мы должны динамически размещать массив в куче. Если мы используем статический массив, он перестает существовать, когда мы выходим из функции, и доступ к нему внутри вызывающей функции приведет к неопределенному поведению.

Это все о возврате нескольких значений из реализации функции на C.

Также см:

Оценить этот пост

Средний рейтинг 4.69 /5. Подсчет голосов: 52

Голосов пока нет! Будьте первым, кто оценит этот пост.

Сожалеем, что этот пост не оказался для вас полезным!

Расскажите, как мы можем улучшить этот пост?

Спасибо за чтение.

Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.

Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂

Подписывайся
5 Комментарии
Большинство голосов
Новейшие Самый старый
Встроенные отзывы
Просмотреть все комментарии
Просмотр комментариев
Загрузить больше комментариев
Просматривать
Подпишитесь на новые публикации

  • Все проблемы
  • Практика DSA
  • 100 самых популярных задач
  • 50 лучших классических задач
  • Лучшие алгоритмы
  • Компилятор С/С++
  • Компилятор Java
  • Компилятор Python
  • Компилятор JavaScript
  • компилятор PHP
  • Компилятор C#
  • Свяжитесь с нами
  • Политика конфиденциальности
  • условия обслуживания
  • Подпишитесь на новые публикации

Techie Delight © 2023 Все права защищены.

Этот веб-сайт использует файлы cookie. Используя этот сайт, вы соглашаетесь с использованием файлов cookie, нашей политикой, условиями авторского права и другими условиями. Читайте наши Политика конфиденциальности. Понятно

Как вернуть несколько значений из функции?

Здравствуйте, пытаюсь написать функцию для генерации чисел, и надо вернуть 3 переменные из функции. Но получается вернуть только одну. Как вернуть несколько переменных из функции в С++?

#include #include using namespace std; int generator() < random_device random_device; mt19937 generator(random_device()); uniform_int_distribution<>distribution(1, 10); int x = distribution(generator); int c = distribution(generator); int answer = x * c; return answer, x, c; > int main()
  • Вопрос задан 03 дек. 2022
  • 457 просмотров

Комментировать
Решения вопроса 1
Wataru @wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.

Кроме параметров функции, можно возвращать структуру с именованными значениями или std::vector или std::touple.

Ответ написан 03 дек. 2022
Нравится 2 6 комментариев
Anonymous @Nikita1244 Автор вопроса

Проблема в том, что предложенное ранее решение не работает.
Про ваше решение можете немного понятнее объяснить, пожалуйста?

Wataru @wataru Куратор тега C++
Никита Савченко, Чего там не работает-то?
Тип функции сделайте s td::vector . Возвращайте
Anonymous @Nikita1244 Автор вопроса
Wataru, я как новичок. Не пойму все равно, что означает ваш std::vector? Погуглил, не понял.
Wataru @wataru Куратор тега C++

Никита Савченко, Это тип. Как int, bool, или char*. std::vector - это класс, который хранит массив int в c++.

Anonymous @Nikita1244 Автор вопроса
Wataru, спасибо, попробую обязательно.
Anonymous @Nikita1244 Автор вопроса

Дошли руки посмотреть Ваше решение, и действительно, решение Александра Ананьева выглядит не элегантно, и оно устарело(Использовалось в последний раз как не-легаси код, судя по всему, в С++ 11).
Сейчас действительно используют std::vector, std::touple

Ответы на вопрос 1

Можно вернуть через параметры функции
void generator(int& answer, int& x, int& c)

#include #include using namespace std; void generator(int& answer, int& x, int& c) < random_device random_device; mt19937 generator(random_device()); uniform_int_distribution<>distribution(1, 10); x = distribution(generator); c = distribution(generator); answer = x * c; > int main()

Ответ написан 03 дек. 2022
Нравится 2 11 комментариев
Anonymous @Nikita1244 Автор вопроса
возвращает в любом случае тогда 1. И ничего более.
Anonymous @Nikita1244 Автор вопроса
не работает в общем-то ваше решение, к сожалению 🙁
Никита Савченко, оно не может не работать. Покажи свой код.
Anonymous @Nikita1244 Автор вопроса

#include #include using namespace std; void generator(int& answer, int& x, int& c) < random_device random_device; mt19937 generator(random_device()); uniform_int_distribution<>distribution(1, 10); int x = distribution(generator); int c = distribution(generator); int answer = x * c; return answer, x, c; > int main()

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

не работает в общем-то ваше решение

Да нет, решение работает. Только Саша, по своему обыкновению, не подумав написал первое что ему в гугле попалось.

При передаче по ссылке тебе не надо возвращать значения, они доступны внутри функции для прямого изменения. Это - сублимация возврата нескольких значений, используемая в палеозойской древности стандарта C++98.
Настоящий возврат набора значений описан только в ответе Wataru.

Но вот в чем дело.
Код return answer, x, c; не должен был родиться в твоем мозгу для функции с типом результата void . Написанное тобой в примере выдает твою полную безграмотность в языке. Даже большую, чем у Саши.
И в этом плане настоящий возврат нескольких значений для тебя просто недосягаем, потому что ты просто не проходишь по знаниям для его использования. Ты ведь даже не знаешь, какой конкретно стандарт C++ ты используешь. А ведь именно от этого зависит решение твоего вопроса.

#include #include using namespace std; void generator(int& answer, int& x, int& c) < random_device random_device; mt19937 generator(random_device()); uniform_int_distribution<>distribution(1, 10); x = distribution(generator); c = distribution(generator); answer = x * c; > int main()

Anonymous @Nikita1244 Автор вопроса

Александр Ананьев, Отредактируй немного ответ, добавив этот код(пусть чисто пример будет в ответе), чтобы людям не копаться в комментариях. Отмечу решением.

Anonymous @Nikita1244 Автор вопроса

Ты ведь даже не знаешь, какой конкретно стандарт C++ ты используешь.

Никогда не думал, что стандарты влияют настолько сильно. Стандарт использую - С++ 17. Хорошо, посмотрю ответ Wataru. Как я понял, решение, которое написал Александр Ананьев, является устаревшим.

Anonymous @Nikita1244 Автор вопроса

Код return answer, x, c; не должен был родиться в твоем мозгу для функции с типом результата void

Тут уже мой косяк, да, но я удалял и код все равно не работал 🙂
Только вот я пробовал по разному писать и всю эту чепуху вам прислал. Так-то да, ретурна судя по всему не должно быть, ибо компилятор и IDE ругаются на него и говорят что ретурна не может быть в void-функции.

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

Стандарт использую - С++ 17.

Да, стандарт языка кардинально влияет на доступные возможности. Смотри вот.

Допустим у тебя есть твоя std::tuple generator() . Это то, о чем написал Wataru. Принять результат ты можешь в такой же кортеж (C++11), можешь воспользоваться обобщением и инициализацией копией (C++11), а можешь воспользоваться std::tie [?] для C++14 или структурным связыванием из C++17.
И все будет зависеть именно от используемого тобой стандарта языка.

И вот, в C++17 у тебя получится такой код:

int main()

При том условии, что ты правильно воспользуешься техникой NRVO, структурное связывание у тебя не приведет к скрытому копированию значения, а все три поля из main будут сразу инициализированы внутри generator .

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

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