вернуть Несколько значений из функции в 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#
Для того чтобы вернуть несколько значений из функции, нужно объявить необходимые параметры с модификаторами out. Например.
class SomeClass < public int getManyData(out object outData1, out object outData2) < // Код функции outData1 = someValue1; // Необходимо инициализировать выходной параметр outData2 = someValue2; // Необходимо инициализировать выходной параметр return result; >>
Отслеживать
ответ дан 20 окт 2010 в 19:56
Nicolas Chabanovsky Nicolas Chabanovsky
51.3k 86 86 золотых знаков 267 267 серебряных знаков 505 505 бронзовых знаков
Отслеживать
ответ дан 20 мар 2011 в 18:02
255 2 2 серебряных знака 8 8 бронзовых знаков
В версиях C# c 4 по 6 включительно, лучшими вариантами вернуть из функции(метода вернее), являлись возвращение кортежа Tuple<> или создание класса\структуры с нужными свойствами. Вариант с out-параметрами, хуже, т.к. немного выбивается из основных парадигм применяемых при разработке на C#, и был встроен скорее для поддержки импорта нативных функций.
На сегодняшний день (C#7) удобной и достаточно качественной альтернативой является использование кортежей поддерживаемых на уровне синтаксиса языка при помощи значимого типа ValueTuple (Правда требуется добавлять библиотеку System.ValueTuple, например через NuGet).
возвращение кортежа Tuple<>
public Tuple GetVasya()
создание класса
class Person < public string Name public int Age > . public Person GetVasya() < return new Person < Name = "Вася", Age = 16 >; >
использование ValueTuple
public (string Name, int Age) GetVasya()
Как вернуть два значения из функции?

Как вернуть из функции два значения
Доброго времени суток! Подскажите, пожалуйста, как вернуть два значения: row и column из функции.

Как вернуть из функции два значения?
Подскажите,как вернуть из ф-ции 2 значения .Вроде ,как то можно с помощью pair ,но как здесь это.

Вернуть из функции два значения
функция должна находить максимальное и минимальное значение используя классы template <class T> T.

Как вернуть два значения из метода?
Как вернуть два значения из метода? При таком коде выдаёт предупреждение cs0162. public static.
![]()
5869 / 4746 / 2940
Регистрация: 20.04.2015
Сообщений: 8,361
1 2 3 4 5
public void Diaginals(out double d1, out double d2) { d1 = //. d2 = //. }
116 / 115 / 64
Регистрация: 03.06.2013
Сообщений: 582
а можно так :
1 2 3 4 5
public double Diaginals(out double d1) { d1 = //. return d2 = //. }
![]()
4431 / 2091 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
1 2 3 4
public Tupledouble, double> GetValues() { return Tuple.Create(1d, 2d); }
Добавлено через 24 секунды
Сообщение от _Denis__ 
вернуть из функции
Вернуть из метода.
Добавлено через 2 минуты
Можно так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public class SomePair { public SomePair() { } public SomePair(double value1, double value2) { Value1 = value1; Value2 = value2; } public double Value1 { get; set; } public double Value2 { get; set; } }
1 2 3 4
public SomePair GetValues() { return new SomePair(1d, 2d); }
Добавлено через 1 минуту
Правда второй вариант имеет смысл, если называть свойства осмысленно, иначе от Tuple не особо отличается.
Добавлено через 4 минуты
Кстати, для этого конкретного случая подошла бы структура, а не класс. Два типа значений (value type) потому что. Хотя зависит от того, как это будет использоваться.
116 / 115 / 64
Регистрация: 03.06.2013
Сообщений: 582
Если человеку надо один это сделать зачем ему отдельный класс и структура.
Добавлено через 1 минуту
С Turple<> соглашусь, что отличный метод, особенно если нужно вернуть значений штук 5.
886 / 587 / 222
Регистрация: 03.07.2013
Сообщений: 1,549
Записей в блоге: 2
Сообщение от MaxSlim 
особенно если нужно вернуть значений штук 5.
![]()
5869 / 4746 / 2940
Регистрация: 20.04.2015
Сообщений: 8,361
Сообщение от rattrapper 
Сообщение от _Denis__ 
Без массива
![]()
4431 / 2091 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
Сообщение от MaxSlim 
Если человеку надо один это сделать зачем ему отдельный класс и структура.
Я где-то уговаривал использовать отдельный класс? Смотря какой проект и вообще от ситуации зависит. Я на работе вносил изменения в один большой проект, так как на работе принцип простой (новая работа) — разбирайся сам. То когда ты вносишь изменения толком не понимая что для чего в этой программе и видишь, как в метод передают Dictionary, Value которого это KeyValuePair, то чтобы ничего не перепутать и не накосячить объявляешь класс, в котором создаёшь 3 именованных свойства и теперь этот класс, как Value у Dictionary (вместо KeyValuePair). Ну и дальше используешь везде этот класс. И с таким подходом уже нереально, что-то дальше напутать, чем с бесконечным множеством вложеных каких-то непонятных пар ключей значений.
Добавлено через 3 минуты
Всякие Tuple и 5 значений удобно использовать особенно во всяких лямбдах, когда ты чётков видишь, что ты только что в Tuple запихал и рядом в другой лямбде это оттуда вытаскиваешь. Ну и ещё некоторые ситуации.
Добавлено через 3 минуты
Я об этом:
1 2 3 4 5 6 7 8 9
Task.Factory.StartNew(() => { return Tuple.Create(1, 2, 3, 4, 5); }).ContinueWith( task => { Tupleint, int, int, int, int> tuple = task.Result; }, TaskScheduler.FromCurrentSynchronizationContext());
Добавлено через 3 минуты
Сообщение от Casper-SC 
чем с бесконечным множеством вложеных каких-то непонятных пар ключей значений.
Многие почему-то не понимают или забивают, что важна читабельность кода, чтобы сразу было всё понятно. А не понты — смотрите, как я умею использовать словарь и знаю о структуре такой-то и давайте я этот словарь прокину ещё в 10 методов и вы думайте потом там, что я прокинул (причём самый первыйметод гигантский, в котром происходят манипуляции с этим словарём в 5 разных циклах, каждый размером с мой монитор в высоту.
Это если ты пишешь софт, то проблем нет. А если потом его изучать другому человеку, то это будет, как минимум, неудобно.
Master of Orion
![]()
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
Сообщение от MaxSlim 
С Turple<> соглашусь, что отличный метод, особенно если нужно вернуть значений штук 5.
Если человеку нужно вернуть значений 5, то тупл тут как раз-таки вообще не к месту. Плохо, что их сделали до 8 параметров, на 3-4 надо было остановиться.
Сообщение от _Denis__ 
Ребят, нужно вернуть из функции два значения. Подскажите как. Без массива
Выше написали, свой класс/стандартный Tuple<>. Все эти out с точки зрения ООП полная ересь.
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
а страдать ООП головного мозга еще большая ересь, кто знает может у него обычная задача в которой ООП как лишняя 3 нога
как вариант использовать в функции класса ref (C# Reference) для параметра(ов)
Master of Orion
![]()
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
агерон, какая разница, ооп или нет? в ФП так вообще функция мало того, что должна возвращать только одно значение, так еще и состояния не должна иметь.
Да и в принципе, лучше кушать ртом, а в туалет ходить другим местом, и не путать эти два понятия. А возвращать данные через входные параметры — это именно оно и есть.
Открою тайну: ref и out в язык добавили только для того, чтобы проще было вызывать PInvoke-код.
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
_Denis__, держи студент
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
public void Diaginals(ref double d1, ref double d2) { double Ax = get_B_x(); double Bx = get_B_x(); double Cx = get_C_x(); double Dx = get_D_x(); double Ay = get_B_y(); double By = get_B_y(); double Cy = get_C_y(); double Dy = get_D_y(); double d1 = DistanceBetweenPoints(Ax,Cx,Ay,Cy); double d2 = DistanceBetweenPoints(Bx,Dx,By,Dy); } public double DistanceBetweenPoints(double x1, double x2, double y1, double y2) { double x1x2 = x1 - x2; double y1y2 = y1 - y2; double SqrX1X2 = Math.Pow(x1x2, 2); double SqrY1Y2 = Math.Pow(x1x2, 2); double result = Math.Sqrt(SqrX1X2 + SqrY1Y2); return result; }
Слона то мы в лавке и не приметили все мы такие функциональные и ООП — шные, а обычную формулу по вычислению расстояния между 2 точками за множеством скобок не увидели, лучше бы студенту обьяснили почему такой код это плохо и как нужно было отрефакторить код
Psilon а может нужно спуститься с небес на грешну землю и признать что за вашу так любимую функциональщину просто не платят в массе своей денег?
и что каждому инструменту свое время и место, а не выпячивать ООП — шность языка во главу угла
Добавлено через 5 минут
P. S. передача параметра по ссылке это не новое изобретение и ref и out оставлены для совместимости не просто так может вспомним что такое стек и как с ним работать да и бинарный код с асмом тоже забывать не стоит
Master of Orion
![]()
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
Сообщение от агерон 
P. S. передача параметра по ссылке это не новое изобретение и ref и out оставлены для совместимости не просто так может вспомним что такое стек и как с ним работать да и бинарный код с асмом тоже забывать не стоит
А, так мы по производительности теперь будем рассуждать?
А по производительности тоже лучше структуры использовать, ибо кэш-линия всего лишь 64 байта, а т.к. локальные данные компилятор может как угодно раскладывать, не факт, что они попадут за один memory call, когда как структура всегда будет.
Хотя о чем я говорю, от void-метода с ref-параметрами веет таким седым винапи, что страшно становится
Добавлено через 46 секунд
Сообщение от агерон 
бинарный код с асмом тоже забывать не стоит
бинарный код с асмом — это кстати для красного словца вставлено? Ибо это одно и то же.
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
Бинарный (Двоичный код) , Что такое ассемблер к сожалению бинарный код и ассемблер это не одно и тоже и я не призываю на них писать я просто прошу не забывать что такое Процедурная парадигма т. к. реализацию к примеру сетевого стека 4 уровня OSI на oCaml не напишешь, еще раз повторяю каждому инструменту свое время и место в данной конкретной задаче ref или out отлично решают проблему возврата результатов вычислений без излишней сложности в виде ООП, на последок прошу вспомните что такое бритва Оккама и угомонитись
484 / 439 / 123
Регистрация: 05.01.2010
Сообщений: 1,848
Сообщение от агерон 
аждому инструменту свое время и место в данной конкретной задаче ref или out отлично решают проблему возврата результатов вычислений без излишней сложности в виде ООП
чисто мое мнение: out уместен только в методах типа
1 2 3 4
bool TryParse( string s, out DateTime result )
или типа такого
1 2 3 4
bool SomeMethod( string s, out string error )
Master of Orion
![]()
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
Сообщение от агерон 
Бинарный (Двоичный код) , Что такое ассемблер
Во-первых ссылаться на википедию как авторитетный источник — так себе идея.
Во-вторых Ассемблер по-определению это просто мнемоничесая запись двоичного кода. То есть add eax ebx и 0241244 это одно и то же, просто записанное на разных языках. Корова и Cow — это тоже разные понятия?
В-третьих oCaml тьюринг-полный язык, и на нем можно написать все что угодно, хоть винду со всеми фреймворками впридачу.
Добавлено через 3 минуты
на последок прошу вспомните что такое бритва Оккама и угомонитись
А это вообще не в тему. С тем же успехом рекомендую банде четырех рассказать, что все, что они навыдумывали — оверинжинеринг, и никому не нужный хлам.
Видал я проекты на десятки мегабайт с таким подходом, в котором потом сами авторы не могли разобраться, что же куда передается. Вместо грамотной архитектуры — груда костылей. Вместо красивого функционального подхода — возня с байтиками, хотя на дворе 21 век.
Ну да, я помню тоже на первом курсе счетчик цикла всегда делал byte, и возмущался, что обычные программисты — транжиры. — делают его int, тратя в 4. раза больше места, хотя значение переменной всегда уложится в byte. Потом немного поумнел, но это другая история.
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
1) видимо вы внятно не читали указанные ссылки
будь у меня на то желание можно написать программу и в троичном (-1,0,1) коде + для него же придумать свой ассемблер,
2.1) ассемблер язык — язык мнемоник упрощающих кодирование инструкций в троичном коде
2.2) ассемблер — программу сборщик обьектных модулей
2.3) линковщик (редактор связей) который из обьектных модулей соберет исполняемый файл
по секрету скажу в том же c# есть и ассемблер и линковщик, ассемблер — IL.exe а вот линковщик не помню как называется
3) ну давайте дерзайте пишите, но только полнофункциональную версию со всеми плюшками, а я возьму побольше колы и попкорна и посмотрю на этот бессмысленный и беспощадный цирк а потом скачаю что то Linux подобное если мне захочеться поэксперементировать, не забывайте что по мере написания ОС на oCaml вам нужно
a) одеваться
b) питаться
c) оплачивать счета
KolibriOS вот тут таки пытаються на асме что то делать и даже получается, ну думаю у вас как программиста на супер удобном функциональном языке уйдет ну лет 25-30 и вы выйдете на уровень поддержки железа как в современной Kolibri
только не забывайте про пункты a) b) c)
еще раз повторяю не флудите и не пытайтесь доказать что вы правы, вы не правы изначально т. к. несмотря на то что C# ООП язык, сама предоставленная задача по вычислению 2 дробных чисел по известным формулам в ООП не нуждается, а значит ООП и функциональщина именно в данном конкретном случае никому не нужный и вредный оверхед
Возврат значений из функции. Оператор return
Функции могут передавать какие-либо данные из своих тел в основную ветку программы. Говорят, что функция возвращает значение. В большинстве языков программирования, в том числе Python, выход из функции и передача данных в то место, откуда она была вызвана, выполняется оператором return .
Если интерпретатор Питона, выполняя тело функции, встречает return , то он «забирает» значение, указанное после этой команды, и «уходит» из функции.
def cylinder(): r = float(input()) h = float(input()) # площадь боковой поверхности цилиндра: side = 2 * 3.14 * r * h # площадь одного основания цилиндра: circle = 3.14 * r**2 # полная площадь цилиндра: full = side + 2 * circle return full square = cylinder() print(square)
3 7 188.4
В данной программе в основную ветку из функции возвращается значение локальной переменной full . Не сама переменная, а ее значение, в данном случае – какое-либо число, полученное в результате вычисления площади цилиндра.
В основной ветке программы это значение присваивается глобальной переменной square . То есть выражение square = cylinder() выполняется так:
- Вызывается функция cylinder() .
- Из нее возвращается значение.
- Это значение присваивается переменной square .
Не обязательно присваивать результат переменной, его можно сразу вывести на экран:
. print(cylinder())
Здесь число, полученное из cylinder() , непосредственно передается функции print() . Если мы в программе просто напишем cylinder() , не присвоив полученные данные переменной или не передав их куда-либо дальше, то эти данные будут потеряны. Но синтаксической ошибки не будет.
В функции может быть несколько операторов return . Однако всегда выполняется только один из них. Тот, которого первым достигнет поток выполнения. Допустим, мы решили обработать исключение, возникающее на некорректный ввод. Пусть тогда в ветке except обработчика исключений происходит выход из функции без всяких вычислений и передачи значения:
def cylinder(): try: r = float(input()) h = float(input()) except ValueError: return side = 2 * 3.14 * r * h circle = 3.14 * r**2 full = side + 2 * circle return full print(cylinder())
Если попытаться вместо цифр ввести буквы, то сработает return , вложенный в except . Он завершит выполнение функции, так что все нижеследующие вычисления, в том числе return full , будут опущены. Пример выполнения:
r None
Но постойте! Что это за слово None , которое нам вернул «пустой» return ? Это ничего, такой объект – «ничто». Он принадлежит классу NoneType . До этого мы знали четыре типа данных, они же четыре класса: int , float , str , bool . Пришло время пятого.
Когда после return ничего не указывается, то по умолчанию считается, что там стоит объект None . При желании мы можете явно писать return None .
Более того. Ранее мы рассматривали функции, которые вроде бы не возвращали никакого значения, потому что в них не было оператора return . На самом деле возвращали, просто мы не обращали на него внимание, не присваивали никакой переменной и не выводили на экран. В Python всякая функция что-либо возвращает. Если в ней нет оператора return , то она возвращает None . То же самое, как если в ней имеется «пустой» return .
Возврат нескольких значений
В Питоне позволительно возвращать из функции несколько объектов, перечислив их через запятую после команды return :
def cylinder(): r = float(input()) h = float(input()) side = 2 * 3.14 * r * h circle = 3.14 * r ** 2 full = side + 2 * circle return side, full s_cyl, f_cyl = cylinder() print("Площадь боковой поверхности %.2f" % s_cyl) print("Полная площадь %.2f" % f_cyl)
Из функции cylinder() возвращаются два значения. Первое из них присваивается переменной s_cyl , второе – f_cyl . Возможность такого группового присвоения – особенность Python, обычно не характерная для других языков:
>>> a, b, c = 10, 15, 19 >>> a 10 >>> b 15 >>> c 19
Фокус здесь в том, что перечисление значений через запятую (например, 10, 15, 19 ) создает объект типа tuple . На русский переводится как «кортеж». Это разновидность структур данных, которые будут изучены позже.
Когда же кортеж присваивается сразу нескольким переменным, то происходит сопоставление его элементов соответствующим в очереди переменным. Это называется распаковкой.
Таким образом, когда из функции возвращается несколько значений, на самом деле из нее возвращается один объект класса tuple . Перед возвратом эти несколько значений упаковываются в кортеж. Если же после оператора return стоит только одна переменная или объект, то ее/его тип сохраняется как есть.
Распаковка не является обязательной. Будет работать и так:
… print(cylinder())
4 3 (75.36, 175.84)
На экран выводится кортеж, о чем говорят круглые скобки. Его также можно присвоить одной переменной, а потом вывести ее значение на экран.
Практическая работа
- Напишите программу, в которой вызывается функция, запрашивающая с ввода две строки и возвращающая в программу результат их конкатенации. Выведите результат на экран.
- Напишите функцию, которая считывает с клавиатуры числа и перемножает их до тех пор, пока не будет введен 0. Функция должна возвращать полученное произведение. Вызовите функцию и выведите на экран результат ее работы.
Примеры решения и дополнительные уроки в pdf-версии курса
X Скрыть Наверх
Python. Введение в программирование