Как вернуть два значения из функции c
Функция в C может возвращать только одно значение. Тем не менее, что если нам надо получить из функции сразу несколько значений? В этом случае мы можем использовать разные подходы. Основные из них — возвращение комплексного объекта, который инкапсулирует отдельные значения, либо использование выходных параметров.
Объединение возвращаемых значений
Наиболее простой способ возвратить из функции несколько значений — это определить структуру для хранения этих значений и возвратить ее. Например, нам надо получить из массива минимальное и максимальное значения. Для этого мы могли определить функцию, которая возвращает структуру с двумя значениями:
#include #include typedef struct < int min; int max; >MinMax; MinMax getMinMax(int* array, size_t length) < assert(length >1 && "Array length is invalid"); MinMax result; result.min = array[0]; result.max = array[0]; for(size_t i = 0; i < length; i++) < if(array[i] < result.min) result.min = array[i]; if(array[i] >result.max) result.max = array[i]; > return result; > int main(void) < int array[] = ; size_t length = sizeof(array) / sizeof(int); MinMax data = getMinMax(array, length); printf("min=%d\n", data.min); // min=2 printf("max=%d\n", data.max); // max=9 >
Здесь для возвращения из функции минимального и максимального значения массива определена структура MinMax, которую возвращает функция getMinMax. Это наиболее простой и очевидный способ возвращения нескольких значений. Однако он имеет свои минусы. Прежде всего нам надо специально определять структуру под возвращаемые значения. Во-вторых, при возвращении структуры происходит копирование ее значений в стеке, что увеличивает объем потребляемой памяти.
Выходные параметры
Другой способ возвратить из функции несколько значений представляют выходные параметры (out-параметры). Язык Си как таковой не имеет концепции выходных параметров функции (как например, C#), однако мы можем симулировать выходные параметры с помощью указателей:
#include #include void getMinMax(int* array, size_t length, int* min, int* max) < assert(length >1 && "Array length is invalid"); *min = array[0]; *max = array[0]; for(size_t i = 0; i < length; i++) < if(array[i] < *min) *min = array[i]; if(array[i] >*max) *max = array[i]; > > int main(void) < int array[] = ; size_t length = sizeof(array) / sizeof(int); int minVal = 0; int maxVal = 0; getMinMax(array, length, &minVal, &maxVal); printf("min=%d\n", minVal); printf("max=%d\n", maxVal); >
Общий механизм определения и передачи выходных параметров заключается в следующем. Во-первых, определяем в функции параметры-указатели:
void getMinMax(int* array, size_t length, int* min, int* max)
Здесь параметры-указатели min и max как представляют выходные параметры. Внутри функции нам не важны их начальные значения. Наоборот, функция устанавливает их значения.
При вызове функции определяются переменные, и их адреса передаются выходным параметрам:
int minVal = 0; int maxVal = 0; getMinMax(array, length, &minVal, &maxVal);
В данном случае выходным параметрам min и max передаются соответственно адреса переменных minVal и maxVal.
При использовании выходных параметров нам не обязательно определять дополнительные структуры. Мы избегаем изличнего копирования возвращаемых значений в стеке. Однако выходные параметры рахдувают определение функции, могут снизить ее читабельность, особенно когда таких параметров много.
Как вернуть два значения из функции c
Go имеет встроенную поддержку нескольких возвращаемых значений. Эта особенность часто применяется в Go, например, для возврата результата функции и ошибки.
package main
import "fmt"
Запись (int, int) в описании этой функции, говорит о том, что функция возвращает два целых числа.
func vals() (int, int) return 3, 7 >
func main()
Здесь функция возвращает два разных значения и присваивает их переменным a,b . Это называется множественное присваивание.
a, b := vals() fmt.Println(a) fmt.Println(b)
Если вы хотите получить не все значения, возвращаемые функцией, то можно поспользоваться пустым идентификатором _ .
_, c := vals() fmt.Println(c) >
$ go run multiple-return-values.go 3 7 7
Принятие переменного количества аргументов — еще одна приятная особенность функций Go; Рассмотрим это дальше.
Как вернуть два значения из функции c
С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал:
#include
#define Numer 7
int main(void)
int massiv( int * ogo , int ugu );
int res[Numer] = < 12, 23, 43, 32, 3, 34, 32 >;
int raz;
raz = massiv( res , Numer );
printf(«Вывод значений «);
>
int massiv( int * ogo , int ugu )
.
return Что_Либо_Только_Одно_Значение;
>
Помогите как в одной ф-ии вернуть сразу два разных значения, или все же придется делать две разные ф-ии ?
дас ист нихьт фантастиш, дас ист руссиш Ванюшка
Re: Функция и возвращение 2-х значений ? Начинающий.
| От: | Mr-Twister | http://cosmozo.narod.ru/ |
| Дата: | 17.02.02 15:06 | |
| Оценка: |
Извените в начале забыл отформатироваьт текст.
С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал:
#include #define Numer 7 int main(void) int massiv( int * ogo , int ugu ); < int res[Numer] = < 12, 23, 43, 32, 3, 34, 32 >; int raz; raz = massiv( res , Numer ); printf("Вывод значений "); > int massiv( int * ogo , int ugu )
Помогите как в одной ф-ии вернуть сразу два разных значения, или все же придется делать две разные ф-ии ?
дас ист нихьт фантастиш, дас ист руссиш Ванюшка
Re: Функция и возвращение 2-х значений ? Начинающий.
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 17.02.02 15:19 | |
| Оценка: | 3 (1) | |
Здравствуйте Mr-Twister, Вы писали:
MT>С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
MT>В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал:
MT>#include MT>#define Numer 7 MT>int main(void) MT>int massiv( int * ogo , int ugu ); MT> < MT>int res[Numer] = < 12, 23, 43, 32, 3, 34, 32 >; MT> int raz; MT> raz = massiv( res , Numer ); MT> printf("Вывод значений "); MT>> MT>int massiv( int * ogo , int ugu ) MT> < MT>. MT> return Что_Либо_Только_Одно_Значение; MT>>
MT>Помогите как в одной ф-ии вернуть сразу два разных значения, или все же придется делать две разные ф-ии ?
Сначала о задании: нигде в нем (в том фрагменте, что ты привел) не сказано, что надо вернуть 2 значения. Сказано: «разность», что есть одно число. А именно, ArrMac — ArrMin = то, что тебе надо вернуть (первдарительно посчитав эти самые ArrMax && ArrMin).
По сути вопроса, оторвавшись от этого конкретного задания:
Есть такая штука в С++, как передача параметров по ссылке. Этот способ в числе прочих преимуществ, о которых здесь пока говорить не будем, дает и такое: появляется возможность изменения значения переменной, объявленной в программе, внутри некоторой функции. Таким образом, появляется возможность определить у функции СКОЛЬКО УГОДНО много возвращаемых значений. Единственное, что отличает этот способ от обычного возврата значения функцией, что это делается не обычной семантикой типа y=f(x), а подругому.
int arg1 = 0, arg2 = 1, arg3 = 1; int FuncMultipleRet( int& a1, int& a2, int& a3 ) < a1 += a2 + a2; a2 += a1 + a3; a3 += a1 + a2; >void main() < printf( "%d, %d, %d\n", arg1, arg2, arg3 )l FuncMultipleRet( arg1, arg2, arg3 ); printf( "%d, %d, %d\n", arg1, arg2, arg3 )l >
В приведенном примере функция делает некоторые вычисления, при этом меняя значения своих аргументов. По окончании функции значения аргументов изменятся, тогда как, если бы они передавались по значения (а не по ссылке), по изменения внутри функции делалиcь бы с локальной копией аргументов, и значения argi не изменились бы по выходе их функции.
Алексей Кирдин
Re[2]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Mr-Twister | http://cosmozo.narod.ru/ |
| Дата: | 17.02.02 15:24 | |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Есть такая штука в С++, как передача параметров по ссылке. Этот способ в числе прочих преимуществ, о которых здесь пока говорить не будем, дает и такое: появляется возможность изменения значения переменной, объявленной в программе, внутри некоторой функции. Таким образом, появляется возможность определить у функции СКОЛЬКО УГОДНО много возвращаемых значений. Единственное, что отличает этот способ от обычного возврата значения функцией, что это делается не обычной семантикой типа y=f(x), а подругому.
Понял Спасибо , а я чего -то и не подумал про изменения параметров по ссылке . Спасибо!
дас ист нихьт фантастиш, дас ист руссиш Ванюшка
Re[2]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 17.02.02 15:26 | |
| Оценка: |
Здравствуйте Mr-Twister, Вы писали:
MT>Извините в начале забыл отформатироваьт текст.
#include
Используй для лучшего эстетического восприятия тэг ccode для кода. написянного на C/C++:
#include
Так красивше будет.
Алексей Кирдин
Re[3]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Mr-Twister | http://cosmozo.narod.ru/ |
| Дата: | 17.02.02 15:31 | |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Так красивше будет.
Окей, буду така делать, правда уже в следующем вопросе.
Еще раз Спасибо.
дас ист нихьт фантастиш, дас ист руссиш Ванюшка
Re: Функция и возвращение 2-х значений ? Начинающий.
| От: | Brother | |
| Дата: | 17.02.02 15:41 | |
| Оценка: | 3 (1) | |
Здравствуйте Mr-Twister, Вы писали:
MT>С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
MT>В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал
Есть несколько вариантов.
Например, возвращай структуру типа такой
struct Diff
int minDiff;
int maxDiff;
>
как то так.
Diff massiv( int * ogo , int ugu)
.
Diff res;
res.minDiff = . ;
res.maxDiff = . ;
return res;
>
Или передавай по ссылке две переменных, в которых будешь возвращать результат, как-то так
void massiv( int * ogo , int ugu, int& diffMin, int& diffMax )
<
.
diffMin = . ;
diffMax = . ;
>
С уважением,
Сергей
Re[2]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Mr-Twister | http://cosmozo.narod.ru/ |
| Дата: | 17.02.02 15:44 | |
| Оценка: |
Здравствуйте Brother, Вы писали:
дас ист нихьт фантастиш, дас ист руссиш Ванюшка
Re: Функция и возвращение 2-х значений ? Начинающий.
| От: | Кодт |
| Дата: | 18.02.02 08:17 |
| Оценка: |
Здравствуйте Mr-Twister, Вы писали:
MT>С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
MT>В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал:
MT>#include
MT>#define Numer 7
MT>int main(void)
MT>int massiv( int * ogo , int ugu );
MT> <
MT> int res[Numer] = < 12, 23, 43, 32, 3, 34, 32 >;
MT> int raz;
MT> raz = massiv( res , Numer );
MT> printf(«Вывод значений «);
MT>>
MT>int massiv( int * ogo , int ugu )
MT> <
MT> .
MT> return Что_Либо_Только_Одно_Значение;
MT>>
MT>Помогите как в одной ф-ии вернуть сразу два разных значения, или все же придется делать две разные ф-ии ?
(Ниже я заменил тип данных на double, чтобы не перепутать значения с индексами)
Способ первый
Сделать функцию с 2 out-параметрами
double Distance(/*in*/ double* data, int length, /*out*/ int* index1, int* index2) < . *index1 = index_of_least; *index2 = index_of_greatest; return data[index_of_greatest] - data[index_of_least]; >
double Distance(/*in*/ const double* data, int length, /*out*/ int& index1, int& index2) < . index1 = index_of_least; index2 = index_of_greatest; return data[index_of_greatest] - data[index_of_least]; >
Pascal/Delphi
function Distance(data:^real; length:integer; var index1:integer; var index2:integer):real;
Способ второй
(пригоден только для С++)
Возвращать объект
struct DISTANCE < int least, greatest; double distance; >; DISTANCE Distance(const double* data, int length) < DISTANCE d; . return d; >
Перекуём баги на фичи!
Re[2]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Аноним |
| Дата: | 18.02.02 08:36 |
| Оценка: |
Здравствуйте Кодт, Вы писали:
К>Здравствуйте Mr-Twister, Вы писали:
MT>>С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
MT>>В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал:
MT>>#include
MT>>#define Numer 7
MT>>int main(void)
MT>>int massiv( int * ogo , int ugu );
MT>> <
MT>> int res[Numer] = < 12, 23, 43, 32, 3, 34, 32 >;
MT>> int raz;
MT>> raz = massiv( res , Numer );
MT>> printf(«Вывод значений «);
MT>>>
MT>>int massiv( int * ogo , int ugu )
MT>> <
MT>> .
MT>> return Что_Либо_Только_Одно_Значение;
MT>>>
MT>>Помогите как в одной ф-ии вернуть сразу два разных значения, или все же придется делать две разные ф-ии ?
К>(Ниже я заменил тип данных на double, чтобы не перепутать значения с индексами)
К>Способ первый
К>Сделать функцию с 2 out-параметрами
К>C:
К>
К>double Distance(/*in*/ double* data, int length, /*out*/ int* index1, int* index2) К> < К>. К> *index1 = index_of_least; К> *index2 = index_of_greatest; К> return data[index_of_greatest] - data[index_of_least]; К>> К>
К>double Distance(/*in*/ const double* data, int length, /*out*/ int& index1, int& index2) К> < К>. К> index1 = index_of_least; К> index2 = index_of_greatest; К> return data[index_of_greatest] - data[index_of_least]; К>> К>
К>Pascal/Delphi
К>
К>function Distance(data:^real; length:integer; var index1:integer; var index2:integer):real; К>
К>Способ второй
К>(пригоден только для С++)
К>Возвращать объект
К>
К>struct DISTANCE К> < К>int least, greatest; К> double distance; К>>; К>DISTANCE Distance(const double* data, int length) К> < К>DISTANCE d; К> . К> return d; К>> К>
А разве Pascal и С не позволяют возвращать структуры.
Re[2]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Mr-Twister | http://cosmozo.narod.ru/ |
| Дата: | 18.02.02 10:20 | |
| Оценка: |
Здравствуйте Кодт, Вы писали:
Спасибо Кодт за ответ, но Вы меня немножко не поняли. Может я плхо задал, но это бывает.
Я имел в виду возвращать значение не с вычислением его в команде return.
А вернуть одновременно два значения сразу, к примеру Max и Min без вычисления.
Я знаю,что можно по ссылке изменить значение без всякого возврата, но в начале хотел выяснить может существует возврат сразу двух значений к одной переменной, в которой была вызвана ф-я. raz = massiv( res , Numer );
А потом эти 2-а значения распределить по двум переменным .
дас ист нихьт фантастиш, дас ист руссиш Ванюшка
Re[3]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Кодт |
| Дата: | 18.02.02 10:55 |
| Оценка: |
Здравствуйте Mr-Twister, Вы писали:
MT>Спасибо Кодт за ответ, но Вы меня немножко не поняли. Может я плхо задал, но это бывает.
MT>Я имел в виду возвращать значение не с вычислением его в команде return.
MT>А вернуть одновременно два значения сразу, к примеру Max и Min без вычисления.
MT>Я знаю,что можно по ссылке изменить значение без всякого возврата, но в начале хотел выяснить может существует возврат сразу двух значений к одной переменной, в которой была вызвана ф-я. raz = massiv( res , Numer );
MT>А потом эти 2-а значения распределить по двум переменным .
Если требуется найти минимальную и максимальную разности (а я думал — индексы элементов) — то подходы остаются те же.
1) через out-параметры
2) через структуру
Эти параметры можно устанавливать как в конце, так и в процессе работы функции.
(просто — один раз в конце — будет быстрее и очевиднее).
Если же хочется сделать так, что функция все еще работает, а клиент уже получил какие-то данные — то это, звините, многопоточность. (тут возможны варианты)
Перекуём баги на фичи!
Re: Функция и возвращение 2-х значений ? Начинающий.
| От: | sluge |
| Дата: | 18.02.02 11:02 |
| Оценка: |
Здравствуйте Mr-Twister, Вы писали:
MT>С функциями возвращающими одно значение разобрался. Но как бы вернуть 2-а значения ?
MT>В задании написано создать ф-ю, которая возвращает разность между наибольшим и наименьшим элементаим в массиве значений. Ну одно значение возвращенное это вроде как я сделал:
MT>#include
MT>#define Numer 7
MT>int main(void)
MT>int massiv( int * ogo , int ugu );
MT> <
MT> int res[Numer] = < 12, 23, 43, 32, 3, 34, 32 >;
MT> int raz;
MT> raz = massiv( res , Numer );
MT> printf(«Вывод значений «);
MT>>
MT>int massiv( int * ogo , int ugu )
MT> <
MT> .
MT> return Что_Либо_Только_Одно_Значение;
MT>>
MT>Помогите как в одной ф-ии вернуть сразу два разных значения, или все же придется делать две разные ф-ии ?
Попробуй сделать так: напиши функцию, которая будет принимать в качестве параметра кроме массива и его длинны специальный параметер, который будет определять, что возвращать-минимум иил максимум. Удачи
Re[4]: Функция и возвращение 2-х значений ? Начинающий.
| От: | Mr-Twister | http://cosmozo.narod.ru/ |
| Дата: | 18.02.02 11:11 | |
| Оценка: |
Здравствуйте Кодт, Вы писали:
Окей, вроде эту тему уже разжевал, поехал я дальше учит C
СЭНКС ВСЕМ! 🙂
Как вернуть несколько значений из функции?
Здравствуйте, пытаюсь написать функцию для генерации чисел, и надо вернуть 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()
- Вопрос задан более года назад
- 697 просмотров
Комментировать
Решения вопроса 1
Wataru @wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Кроме параметров функции, можно возвращать структуру с именованными значениями или std::vector или std::touple.
Ответ написан более года назад
Нравится 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()
Ответ написан более года назад
Нравится 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 .
Оператор 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
Функция в C может возвращать только одно значение. Тем не менее, что если нам надо получить из функции сразу несколько значений? В этом случае мы можем использовать разные подходы. Основные из них — возвращение комплексного объекта, который инкапсулирует отдельные значения, либо использование выходных параметров.
Объединение возвращаемых значений
Наиболее простой способ возвратить из функции несколько значений — это определить структуру для хранения этих значений и возвратить ее. Например, нам надо получить из массива минимальное и максимальное значения. Для этого мы могли определить функцию, которая возвращает структуру с двумя значениями:
#include #include typedef struct < int min; int max; >MinMax; MinMax getMinMax(int* array, size_t length) < assert(length >1 && "Array length is invalid"); MinMax result; result.min = array[0]; result.max = array[0]; for(size_t i = 0; i < length; i++) < if(array[i] < result.min) result.min = array[i]; if(array[i] >result.max) result.max = array[i]; > return result; > int main(void) < int array[] = ; size_t length = sizeof(array) / sizeof(int); MinMax data = getMinMax(array, length); printf("min=%d\n", data.min); // min=2 printf("max=%d\n", data.max); // max=9 >
Здесь для возвращения из функции минимального и максимального значения массива определена структура MinMax, которую возвращает функция getMinMax. Это наиболее простой и очевидный способ возвращения нескольких значений. Однако он имеет свои минусы. Прежде всего нам надо специально определять структуру под возвращаемые значения. Во-вторых, при возвращении структуры происходит копирование ее значений в стеке, что увеличивает объем потребляемой памяти.
Выходные параметры
Другой способ возвратить из функции несколько значений представляют выходные параметры (out-параметры). Язык Си как таковой не имеет концепции выходных параметров функции (как например, C#), однако мы можем симулировать выходные параметры с помощью указателей:
#include #include void getMinMax(int* array, size_t length, int* min, int* max) < assert(length >1 && "Array length is invalid"); *min = array[0]; *max = array[0]; for(size_t i = 0; i < length; i++) < if(array[i] < *min) *min = array[i]; if(array[i] >*max) *max = array[i]; > > int main(void) < int array[] = ; size_t length = sizeof(array) / sizeof(int); int minVal = 0; int maxVal = 0; getMinMax(array, length, &minVal, &maxVal); printf("min=%d\n", minVal); printf("max=%d\n", maxVal); >
Общий механизм определения и передачи выходных параметров заключается в следующем. Во-первых, определяем в функции параметры-указатели:
void getMinMax(int* array, size_t length, int* min, int* max)
Здесь параметры-указатели min и max как представляют выходные параметры. Внутри функции нам не важны их начальные значения. Наоборот, функция устанавливает их значения.
При вызове функции определяются переменные, и их адреса передаются выходным параметрам:
int minVal = 0; int maxVal = 0; getMinMax(array, length, &minVal, &maxVal);
В данном случае выходным параметрам min и max передаются соответственно адреса переменных minVal и maxVal.
При использовании выходных параметров нам не обязательно определять дополнительные структуры. Мы избегаем изличнего копирования возвращаемых значений в стеке. Однако выходные параметры рахдувают определение функции, могут снизить ее читабельность, особенно когда таких параметров много.
Как вернуть два значения из функции c
Go имеет встроенную поддержку нескольких возвращаемых значений. Эта особенность часто применяется в Go, например, для возврата результата функции и ошибки.
package main
import "fmt"
Запись (int, int) в описании этой функции, говорит о том, что функция возвращает два целых числа.
func vals() (int, int) return 3, 7 >
func main()
Здесь функция возвращает два разных значения и присваивает их переменным a,b . Это называется множественное присваивание.
a, b := vals() fmt.Println(a) fmt.Println(b)
Если вы хотите получить не все значения, возвращаемые функцией, то можно поспользоваться пустым идентификатором _ .
_, c := vals() fmt.Println(c) >
$ go run multiple-return-values.go 3 7 7
Принятие переменного количества аргументов — еще одна приятная особенность функций Go; Рассмотрим это дальше.
Как вернуть два значения из функции 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 применяется, если название возвращаемого типа довольно большое и сложное, что позволит сократить код.