Что значит вернуть значение

Primary tabs

picture 19 1455465074

Forums:

В коде программы все что вы видите можно разделить на:

Некоторые действия вместе с данными образуют выражения или вызовы подпрограмм. И первые, и вторые «возвращают значение».

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

Использование/игнорирование возвращаемого значения

Получать возвращаемое значение, нужно явно, используя (как было сказано выше) или для присваивания или как часть выражения.э

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

— тут присваивание, теперь в переменной а лежит число 14.

— тут часть выражения, а потом присваивание:
сначала вызов f1(2) возвращает 7 в выражение 5 + 7 а потом уже происходит запись результата данного выражения в переменную a.

— результат f1() используется, как входные данные для какой-то другой функции f2().

Все три примера выше это полезное (в смысле получения возвращаемого значения) использование, а теперь глянем на пример с игнорированием:

— пример игнорирования возвращаемого результата, так как то, что возвращается никуда не записывается и не передается, значение переменной a по-прежнему =3, хотя вызов f1(a) и вернул число 8, но это число не было использовано в выражении или для записи в переменную.

Выражения и их значения (как «возвращаемые»)

В случае с операторами (с их помощью и строятся выражения, в частности арифметические) понятно, что, например, знак «+» возвращает результат, суммы, т.е. что во многих ЯП в переменную «a» будет возвращена сумма, например (синтаксис Паскаля):

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

Что значит «функция возвращает значение»? Возврат значений подпрограммой

То, что функция «возвращает значение», фактически означает, что результат её вызова может быть использован:

— и то, и другое возможно как раз потому, что вызов функции «возвращает значение».

или как часть выражения, например:

Понятие возврата значений очень тесно связано с понятием области видимости.
Дело в том, что во многих ЯП код функции выполняется в изолированной области памяти и все переменные, которые передаются в функцию (если только это не передача «по ссылке»), как бы «копируются» в изолированное пространство, никак не влияющее на жизнь вызвавшего функцию кода. Поэтому, чтобы вернуть результат работы функции наружу, часто используют какое-то специальное слово, например return в С-подобных ЯП.

Фактически, если функция не возвращает значения и не оказывает никакого побочного эффекта, то это значит, что данная функция никак не влияет на работу программы.

Пример бесполезной функции (синтаксис PHP)

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

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

(без явной инструкции система не поймёт, что именно возвращать, ведь функция может быть очень сложной, в ней может быть большое количество переменных). Также в данном случае можно было сразу вернуть результат выражения, без использования локальной переменной total:

Источник

11.5 – Возвращение значений по значению, по ссылке и по адресу

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

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

Возврат по значению

Возврат по значению – это самый простой и безопасный тип возврата значения. Когда значение возвращается по значению, вызывающему возвращается копия этого значения. Как и в случае передачи по значению, вы можете возвращать значения литералов (например, 5), переменных (например, x ) или выражений (например, x + 1 ), что делает возврат по значению очень гибким.

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

Читайте также:  Что делать мужчине с сединой

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

Когда использовать возврат по значению:

Когда не использовать возврат по значению:

Возврат по адресу

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

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

Как вы можете видеть здесь, value уничтожается сразу после того, как его адрес возвращается вызывающему. Конечным результатом является то, что вызывающий получает адрес невыделенной памяти (висячий указатель), что вызовет проблемы при использовании. Это частая ошибка, которую допускают начинающие программисты. Многие более новые компиляторы выдают предупреждение (а не ошибку), если программист пытается вернуть локальную переменную по адресу – однако есть довольно много способов обмануть компилятор, чтобы он позволил вам сделать что-то нелегальное без генерации предупреждения, поэтому эта ответственность лежит на программисте, чтобы гарантировать, что указатель, который он возвращает, после возврата из функции будет указывать на допустимую переменную.

Возврат по адресу часто использовался для возврата вызывающему динамически выделенной памяти:

Это работает, потому что динамически выделяемая память не выходит за пределы области действия в конце блока, в котором она объявлена, поэтому эта память всё еще будет существовать, когда ее адрес возвращается обратно вызывающему. Отслеживание ручного распределения памяти может быть трудным. Разделение выделения и освобождения на разные функции еще больше затрудняет понимание того, кто несет ответственность за удаление ресурса и нужно ли вообще удалять ресурс. Вместо ручного управления памятью следует использовать умные указатели (рассматриваются позже) и типы, которые сами выполняют очистку после себя.

Когда использовать возврат по адресу:

Когда не использовать возврат по адресу:

Возврат по ссылке

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

Однако, как и при возврате по адресу, вы не должны возвращать по ссылке локальные переменные. Рассмотрим следующий пример:

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

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

Хотя это в некоторой степени надуманный пример (потому что вы можете получить доступ к array[10] напрямую), как только вы узнаете о классах, вы найдете гораздо больше применений для возврата значений по ссылке.

Когда использовать возврат по ссылке:

Когда не использовать возврат по ссылке:

Смешивание возвращаемых ссылок и значений

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

Продление времени жизни не сохраняет висячие ссылки

Рассмотрим следующую программу:

В приведенной выше программе returnByReference() возвращает константную ссылку на значение, которое выйдет за пределы области видимости при завершении функции. Обычно это недопустимо, так как это приведет к висячей ссылке. Однако мы также знаем, что присвоение значения константной ссылке может продлить время жизни этого значения. Итак, что здесь имеет приоритет? Что раньше, 5 выходит из области видимости, или ref продлевает срок жизни 5?

Читайте также:  Чему равен египетский фунт в рублях

Ответ заключается в том, что сначала 5 выходит за пределы области видимости, затем ссылка на 5 копируется обратно вызывающему, а затем ref продлевает время жизни теперь уже висячей ссылки.

Однако следующий код работает должным образом:

В этом случае литеральное значение 5 сначала копируется обратно в область видимости вызывающего ( main ), а затем ref продлевает время жизни этой копии.

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

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

К счастью, есть несколько косвенных методов, которые можно использовать.

Как описано в уроке «11.3 – Передача аргументов по ссылке», выходные параметры предоставляют первый метод для передачи нескольких значений данных обратно вызывающему. Мы не рекомендуем этот метод.

Второй метод предполагает использование структуры только для данных:

Вот пример, который возвращает кортеж и использует std::get для получения n-го элемента кортежа:

Это работает идентично предыдущему примеру.

Вы также можете использовать std::tie для распаковки кортежа в предопределенные переменные, например:

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

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

Заключение

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

Небольшой тест

std::max_element – стандартная функция.

Источник

Вызываем методы, возвращаем значение

— Ладно, давай зайдем с другой стороны. Я тебе сейчас расскажу как работает вызов методов, а ты потом еще раз попробуешь пробежаться по предыдущей лекции, ок?

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

— Команды группируют в функции, чтобы потом можно было исполнять их единым блоком – как одну сложную команду. Для этого надо написать имя функции(метода) и в скобках после него перечислить значения-параметры.

— В примере выше мы написали функцию, которая выводит на экран переданную строку 4 раза. Затем мы вызвали функцию print4 в строке номер 6.

— Когда программа дойдет до выполнения строчки 6, она перескачет на строчку 9 – переменной s будет присвоено значение “I like to move it, move it.”

— Затем будут выполнены строки 11-14, и, наконец, функция завершится и программа продолжит работу со строчки номер 7.

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

— Похоже, начинаю понимать. Слева и справа написан один и тот же код. Просто слева он вынесен в отдельную функцию.

— Функция вычисляет какое-то значение и отдает его тем, кто ее вызвал с помощью команды return. По крайней мере, мне так кажется.

— А что еще за тип void такой?

— Некоторые функции просто что-то делают, но никаких значений не вычисляют и не возвращают, как наш метод main(), например. Для них придуман специальный тип результата – void – пустой тип.

— А почему нельзя было просто ничего не указывать, раз функция ничего не возвращает?

— Вспомни, как объявляется любая переменная – «тип и имя». А функция – «тип, имя и круглые скобки». А имя функции и затем круглые скобки – это вызов функции!

— Т.е. было проще придумать «пустой тип», чем разделять функции на две категории – возвращающие значение и не возвращающие значение?

— Именно! Ты отлично соображаешь, мой мальчик.

— А как возвращать пустой тип?

— Никак. Вот как все это работает: когда Java-машина выполняет команду return, она вычисляет значение выражения, стоящего справа от слова return, сохраняет это значение в специальной части памяти и тут же завершает работу функции. А сохранённое значение использует как результат вызова функции в том месте, где её вызвали. Ты можешь увидеть это на примере вверху.

Читайте также:  Что делать с поврежденным жестким диском

— Ты говоришь про то место, где int m = min(a,b) трансформировалось в m=m2?

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

— По-моему это только кажется лёгким, а на самом деле – сложно. Я только чуть-чуть чего-то понял и всё.

— Ничего. С первого раза можно понять только то, что уже знаешь. Чем больше не понятно, тем сильнее ты влез в новую для тебя область. И тем круче будет результат. Со временем всё прояснится.

— Ну, если ты так говоришь, тогда поехали дальше.

Источник

Возврат значения функции

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

tickВозврат значения из полиморфной функции
Доброго времени суток всем. Ребят не знаю как правильно сформулировать свой вопрос. Суть вот в чем.

Неправильный возврат значения функции
При компиляции если значение меньше или равно 100 программа прекращает работу а если значение выше.

Вот тут я сделал простой пример:

Ну, во первых bat-, bash-скрипты умеют анализировать код возврата программы. А во-вторых уже и не требуетсяsmile3

Добавлено через 8 минут
ИМХО, топик был создан не без лукавства. Просто ТС таким образом решил заставить нас еще больше полюбить функцию, и за одно понять, за что же мы ее так любим smile3

Добавлено через 5 минут
Nick Alte, Я же сказал, что это для меня. Как МНЕ кажется, функции выполняющие роль конструкторов, деструкторов и методов класса намного более захватывающие, чем обычные вялые функции, которые выполняют определенную последовательность действий при вызове(да да, я знаю, что методы класса делают так же, но они методы класса! smile3). Лично я влюбился в функции после того как познакомился с объектами. Говорю это как человек, который все еще изучает программирование в институте(6 семестр).

Источник

Возвращаемое значение

Возвращаемое значение функции — это значение возвращаемое в точку вызова функции, после её выполнения, причём значение может и не возвращаться, так как пользователь указывал на тип данных функции — void (в языке C++).

Оптимизация возвращаемого значения

Пример

Полезное

Смотреть что такое «Возвращаемое значение» в других словарях:

возвращаемое функцией значение — — [Л.Г.Суменко. Англо русский словарь по информационным технологиям. М.: ГП ЦНИИС, 2003.] Тематики информационные технологии в целом EN return value … Справочник технического переводчика

Printf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки … Википедия

Snprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Sprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Swprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Vasprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Vfprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Vsprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Vprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Vsnprintf — printf обобщённое название семейства функций или методов стандартных или широкоизвестных коммерческих библиотек, или встроенных операторов некоторых языков программирования, используемых для форматного вывода вывода в различные потоки значений… … Википедия

Источник

Adblock
detector