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

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

  • автор:

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

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

Отслеживать
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков
задан 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
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков

Дополню ответ @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,691 1 1 золотой знак 17 17 серебряных знаков 31 31 бронзовый знак

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

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

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

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

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

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

Оператор return (C)

Оператор return завершает выполнение функции и возвращает управление вызывающей функции. Выполнение возобновляется в вызывающей функции в точке сразу после вызова. Оператор return может возвращать значение, передавая его вызывающей функции. Дополнительные сведения см. в статье Тип возвращаемого значения.

Синтаксис

jump-statement :
return expression необ. ;

Значение expression , если оно имеется, возвращается вызывающей функции. Если expression параметр опущен, возвращаемое значение функции не определено. Параметр "выражение", если он присутствует, вычисляется и преобразуется к типу, возвращаемому функцией. Если оператор return содержит выражение в функциях, имеющих тип возвращаемого значения void , то компилятор выдает предупреждение, а выражение не вычисляется.

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

В качестве лучшей методики разработки рекомендуется всегда указывать тип возвращаемого значения для ваших функций. Если возвращаемое значение не требуется, объявите функцию как имеющую тип возвращаемого значения void . Если тип возвращаемого значения не указан, компилятор C предполагает, что по умолчанию используется тип возвращаемого значения int .

Многие программисты используют круглые скобки для заключения expression аргумента return оператора . Однако использовать эти скобки в языке C необязательно.

Если компилятор обнаруживает операторы, размещенные после return , он может вывести предупреждающее диагностическое сообщение о недоступном для выполнения коде.

В функции main оператор return и выражение являются необязательными. То, что происходит с указанным возвращаемым значением, зависит от реализации. Только для Майкрософт:реализация C от Майкрософт возвращает значение выражения процессу, вызвавшему программу, например cmd.exe . Если выражение return не указано, среда выполнения C от Майкрософт возвращает значение, соответствующее успешному (0) или неудачному (ненулевое значение) выполнению.

Пример

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

// C_return_statement.c // Compile using: cl /W4 C_return_statement.c #include // for INT_MAX #include // for printf long long square( int value ) < // Cast one operand to long long to force the // expression to be evaluated as type long long. // Note that parentheses around the return expression // are allowed, but not required here. return ( value * (long long) value ); >

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

Скобки вокруг выражения return в функции square вычисляются как часть выражения, и использовать их в операторе return не требуется.

double ratio( int numerator, int denominator ) < // Cast one operand to double to force floating-point // division. Otherwise, integer division is used, // then the result is converted to the return type. return numerator / (double) denominator; >

Функция ratio возвращает частное двух int аргументов в виде значения double с плавающей запятой. Выражение return принудительно использует операцию с плавающей запятой путем приведения одного из операндов к типу double . В противном случае будет использоваться оператор целочисленного деления, а дробная часть будет потеряна.

void report_square( void ) < int value = INT_MAX; long long squared = 0LL; squared = square( value ); printf( "value = %d, squared = %lld\n", value, squared ); return; // Use an empty expression to return void. >

Функция report_square вызывает square со значением параметра INT_MAX — самым большим целым числом со знаком, которое помещается в int . Результат типа long long сохраняется в squared , а затем выдается в выводе. Функция report_square имеет тип возвращаемого значения void , поэтому она не содержит выражения в операторе return .

void report_ratio( int top, int bottom ) < double fraction = ratio( top, bottom ); printf( "%d / %d = %.16f\n", top, bottom, fraction ); // It's okay to have no return statement for functions // that have void return types. >

Функция report_ratio вызывает ratio со значениями параметров 1 и INT_MAX . Результат типа double сохраняется в fraction , а затем выдается в выводе. Функция report_ratio имеет тип возвращаемого значения void , поэтому явно возвращать значение не требуется. Выполнение report_ratio не дает результата и не возвращает вызывающей функции никакого значения.

int main()

Функция main вызывает две функции: report_square и report_ratio . Поскольку report_square не принимает параметров и возвращает void , результат не присваивается переменной. Аналогичным образом функция report_ratio возвращает void , поэтому ее возвращаемое значение тоже не сохраняется. После вызова каждой из этих функций выполнение продолжается в следующем операторе. Затем main возвращает значение 0 (обычно свидетельствующее об успешном выполнении), чтобы завершить программу.

Чтобы скомпилировать пример, создайте файл исходного кода с именем C_return_statement.c . Затем скопируйте весь пример кода в показанном здесь порядке. Сохраните файл и скомпилируйте его в окне Командной строки разработчика с помощью следующей команды:

cl /W4 C_return_statement.c

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

value = 2147483647, squared = 4611686014132420609 1 / 2147483647 = 0.0000000004656613 

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

Для возвращения результата из функции применяется оператор return . Этот оператор имеет две формы:

return выражение; return;

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

Единственная функция, которая возвращает некоторое значение, и где можно не использовать оператор return - это функция main .

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

#include #include int sum(int, int); int main() < int result = sum(10, 6); // 16 std::cout int sum(int n, int m)

Здесь функция sum, которая вычисляет сумму чисел, принимает два значения типа int и возвращает значение типа int , поэтому прототип функции выглядит следующим образом

int sum(int, int);

И в этом случае в функции sum необходимо использовать оператор return , после которого идет возвращаемое значение:

int res = n + m; return res;

В данном случае возвращается значение переменной res . Хотя это могло бы быть сложное выражение, которое возвращало число int, например:

int sum(int n, int m)

Так как функция sum возвращает значение, то ее результат можно присвоить какой-нибудь переменной или константе:

int result = sum(10, 6); // 16 std::cout 

Либо напрямую использовать результат функции sum, как число, например, при выводе на консоль:

std::cout 

Рассмотрим еще один пример:

#include int calculate(int, int, char); int main() < std::cout int calculate(int n, int m, char op) < switch(op) < case '+': return n + m; case '-': return n - m; case '*': return n * m; default: return 0; >>

Здесь определена функция calculate , которая также принимает два числа и символ - знак операции. В конструкции switch в зависимости от знака операции с помощью оператора return возвращается результат определенной операции

return без возвращения значения

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

Например, функция принимает имя и возраст пользователя и выводит их на консоль:

#include #include void print(std::string, unsigned); int main() < print("Tom", 38); // Name: Tom Age: 38 print("Bob", 2500); // Incorrect age >void print(std::string name, unsigned age) < // если запредельный возраст if(age >120) < std::cout std::cout

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

Выведение типа результата

Компилятор С++ может автоматически выводить тип возвращаемого значения, если вместо возвращаемого типу используется оператор auto :

#include // автоматически выводится возвращаемый тип auto sum(int a, int b) < return a + b; >int main() < std::cout 

Здесь тип результата в функции sum выводится автоматически. Поскольку возвращется сумма a + b , результат которой будет представлять тип int , соответственно компилятор выведет, что функция возвращает тип int. Стоит отметить, что функция sum определена до того, как она вызывается в функции main.

В данном случае нет большого смысла использовать оператор auto вместо int . Обычно auto применяется, если название возвращаемого типа довольно большое и сложное, что позволит сократить код.

вернуть Несколько значений из функции в 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.)

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

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