Что такое возвращаемое значение функции
Функции в языке Си
Функция — это самостоятельная единица программы, которая спроектирована для реализации конкретной подзадачи.
Функция является подпрограммой, которая может содержаться в основной программе, а может быть создана отдельно (в библиотеке). Каждая функция выполняет в программе определенные действия.
Сигнатура функции определяет правила использования функции. Обычно сигнатура представляет собой описание функции, включающее имя функции, перечень формальных параметров с их типами и тип возвращаемого значения.
Семантика функции определяет способ реализации функции. Обычно представляет собой тело функции.
Определение функции
Каждая функция в языке Си должна быть определена, то есть должны быть указаны:
Определение функции имеет следующий синтаксис:
Пример : Функция сложения двух вещественных чисел
Различают системные (в составе систем программирования) и собственные функции.
Собственные функции — это функции, написанные пользователем для решения конкретной подзадачи.
Разбиение программ на функции дает следующие преимущества:
С точки зрения вызывающей программы функцию можно представить как некий «черный ящик», у которого есть несколько входов и один выход. С точки зрения вызывающей программы неважно, каким образом производится обработка информации внутри функции. Для корректного использования функции достаточно знать лишь ее сигнатуру.
Вызов функции
Общий вид вызова функции
Фактический аргумент — это величина, которая присваивается формальному аргументу при вызове функции. Таким образом, формальный аргумент — это переменная в вызываемой функции, а фактический аргумент — это конкретное значение, присвоенное этой переменной вызывающей функцией. Фактический аргумент может быть константой, переменной или выражением. Если фактический аргумент представлен в виде выражения, то его значение сначала вычисляется, а затем передается в вызываемую функцию. Если в функцию требуется передать несколько значений, то они записываются через запятую. При этом формальные параметры заменяются значениями фактических параметров в порядке их следования в сигнатуре функции.
Возврат в вызывающую функцию
По окончании выполнения вызываемой функции осуществляется возврат значения в точку ее вызова. Это значение присваивается переменной, тип которой должен соответствовать типу возвращаемого значения функции. Функция может передать в вызывающую программу только одно значение. Для передачи возвращаемого значения в вызывающую функцию используется оператор return в одной из форм:
Действие оператора следующее: значение выражения, заключенного в скобки, вычисляется и передается в вызывающую функцию. Возвращаемое значение может использоваться в вызывающей программе как часть некоторого выражения.
Оператор return также завершает выполнение функции и передает управление следующему оператору в вызывающей функции. Оператор return не обязательно должен находиться в конце тела функции.
Пример : Посчитать сумму двух чисел.
В языке Си нельзя определять одну функцию внутри другой.
В языке Си нет требования, чтобы семантика функции обязательно предшествовало её вызову. Функции могут определяться как до вызывающей функции, так и после нее. Однако если семантика вызываемой функции описывается ниже ее вызова, необходимо до вызова функции определить прототип этой функции, содержащий:
Прототип необходим для того, чтобы компилятор мог осуществить проверку соответствия типов передаваемых фактических аргументов типам формальных аргументов. Имена формальных аргументов в прототипе функции могут отсутствовать.
Если в примере выше тело функции сложения чисел разместить после тела функции main, то код будет выглядеть следующим образом:
Рекурсивные функции
Рекурсия — вызов функции из самой функции.
Пример рекурсивной функции — функция вычисления факториала.
Результат выполнения
Более подробно рекурсивные функции рассмотрены в этой статье.
Математические функции
Основные математические функции стандартной библиотеки.
Функция | Описание |
int abs( int x) | Модуль целого числа x |
double acos( double x) | Арккосинус x |
double asin( double x) | Арксинус x |
double atan( double x) | Арктангенс x |
double cos( double x) | Косинус x |
double cosh( double x) | Косинус гиперболический x |
double exp( double x) | Экспонента x |
double fabs( double x) | Модуль вещественного числа |
double fmod( double x, double y) | Остаток от деления x/y |
double log( double x) | Натуральный логарифм x |
double log10( double x) | Десятичный логарифм x |
double pow( double x, double y) | x в степени y |
double sin( double x) | Синус x |
double sinh( double x) | Синус гиперболический x |
double sqrt( double x) | Квадратный корень x |
double tan( double x) | Тангенс x |
double tanh( double x) | Тангенс гиперболический x |
Особенности использования функций в языке C++ рассмотрены в этой статье.
Комментариев к записи: 97
#include
#include
#include
#include
int main()
<
srand(time( NULL ));
int z[6][5];
int s;
int i, j;
int max, min;
input(z);
output(z);
actions(z);
Output_MaxMin(max, min);
getchar();
return 0;
>
int input( int z[6][5]) <
int * a = z;
int i, j;
for (i = 0; i for (j = 0; j return *a;
>
int output( int * a) <
int actions( int z) <
int summa[6];
int * a = z;
int * p = summa;
int max, min;
§14 Функции возвращающие значение. Перегрузка функций. Шаблоны. Раздельная компиляция
Функции возвращающие значение
Функция в программе
Объявление функции. Прототип
Вызов функции
Определение функции
Инструкция return
Решение этой задачи можно оформить и по другому. Такой способ называется декомпозиция. Декомпозиция позволяет получить связь данных, находящихся в структуре, с переменными, используя спецификатор auto и [] следующим образом:
Мы вернемся к формату кода с декомпозицией. Важно запомнить, что выражение справа может быть пара, кортеж, массив фиксированного размера или структура с нестатическими членами. С понятием структуры мы вскоре познакомимся.
Перегрузка функций
Перегрузка функций позволяет использовать несколько функций с одним и тем же именем, но различными параметрами. Каждая такая функция должна иметь свой прототип и свое определение. Вызов той или иной перегруженной функции будет определять набор аргументов (сигнатура). Сигнатуры перегруженных функций должны различаться либо по типу, либо по количеству, либо и по тому, и по другому. Рассмотрим простой пример. Требуется составить программу которая выводит половину произведения аргументов, если в сигнатуре два аргумента и среднее арифметическое аргументов, если в сигнатуре три аргумента.
Перегрузка функций, так называемый полиморфизм функций, применяется в том случае, если в большой программе существует набор некоторых функций, которые решают однотипные задачи (один класс задач), но реализация каждой из них требует некоторых изменений (например, использование иных типов данных или иного представления результата). Это позволяет разработчику сократить количество используемых имен функций в своей программе.
Заметим так же, что перегруженные функции могут возвращать разный тип данных, при условии, что сигнатуры этих функций будут различаться.
Шаблоны функций
Раздельная компиляция
- константы прототипы объявление классов и структур объявление шаблонов встроенные функции
В заголовочном файле (назовем его chisla.h ) перечислим прототипы функций, которые мы будем использовать в программе:
- 1. Составить программу в которой используется функция нахождения максимального из двух чисел.2. Составить программу в которой бы использовалась логическая функции, определяющая четное ли введенное число k.
Вариант функции с использованием операции % – взятия остатка от деления:
5. Составить программу в которой используется функция для вычисления F(x):
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Курсы по C++
Заметки
Фаза Луны
Страница
Дата создания:
2015-08-12 19:34:43
Последняя правка:
2021-08-13 10:03:06
Возвращаемые значения функций
Для нас в этом курсе имеется ещё один важный момент. Посмотрим внимательнее на возвращаемое значение функций. Некоторые функции не возвращают существенное значение после завершения, но некоторые возвращают, и важно понимать что это за значение и как использовать его в своём коде и как сделать так чтобы ваши собственные функции возвращали полезные значения. Мы объясним всё это ниже.
Необходимые навыки: | |
---|---|
Цели: | Понять что такое возвращаемое значение функции и как его использовать. |
Что из себя представляют возвращаемые значения?
Если вы посмотрите на функцию replace() на MDN reference page, вы увидите секцию под названием Return value. Очень важно знать и понимать какие значения возвращаются функциями, так что мы пытаемся включать эту информацию везде, где это возможно.
Некоторые функции не возвращают значения( на наших reference pages, возвращаемое значение обозначено как void или undefined в таких случаях). Например, в функции displayMessage() которую мы сделали в прошлой статье, в результате выполнения функции не возвращается никакого значения. Функция всего лишь отображает что-то где-то на экране.
В основном, возвращаемое значение используется там, где функция является чем-то вроде вспомогательного звена при вычислениях. Вы хотите получить результат, который включает в себя некоторые значения. Эти значения вычисляются функцией, которая возвращает результат так, что он может быть использован в следующих стадиях вычисления.
Использование возвращаемых значений в ваших собственных функциях
Тоже самое может быть написано вот так:
Но первую версию написать быстрее и она более компактна.
Мы возвращаем результат вычисления Math.floor(Math.random()*number) каждый раз когда функция вызывается. Это возвращаемое значение появляется в момент вызова функции и код продолжается. Так, например, если мы выполним следующую строчку:
и 3 вызова random() вернут значения 500, 200 и 35, соответственно, строчка будет выполнена как если бы она была такой:
Активное обучение: наша собственная, возвращающая значение функция
Теперь напишем нашу собственную возвращающую значение функцию.
Урок №12. Функции
Обновл. 26 Ноя 2021 |
Вы уже знаете, что каждая программа должна содержать функцию main() (с которой она и начинает свое выполнение). Тем не менее, большинство программ используют и много других функций.
Функции
Функция — это последовательность стейтментов для выполнения определенного задания. Часто ваши программы будут прерывать выполнение одних функций ради выполнения других. Вы делаете аналогичные вещи в реальной жизни постоянно. Например, вы читаете книгу и вспомнили, что должны были сделать телефонный звонок. Вы оставляете закладку в своей книге, берете телефон и набираете номер. После того, как вы уже поговорили, вы возвращаетесь к чтению: к той странице, на которой остановились.
Программы на языке C++ работают похожим образом. Иногда, когда программа выполняет код, она может столкнуться с вызовом функции. Вызов функции — это выражение, которое указывает процессору прервать выполнение текущей функции и приступить к выполнению другой функции. Процессор «оставляет закладку» в текущей точке выполнения, а затем выполняет вызываемую функцию. Когда выполнение вызываемой функции завершено, процессор возвращается к закладке и возобновляет выполнение прерванной функции.
Функция, в которой находится вызов, называется caller, а функция, которую вызывают — вызываемая функция, например:
Результат выполнения программы:
Starting main()
In doPrint()
Ending main()
Правило: Не забывайте указывать круглые скобки () при вызове функций.
Возвращаемые значения
Когда функция main() завершает свое выполнение, она возвращает целочисленное значение обратно в операционную систему, используя оператор return.
Функции, которые мы пишем, также могут возвращать значения. Для этого нужно указать тип возвращаемого значения (или «тип возврата»). Он указывается при объявлении функции, перед её именем. Обратите внимание, тип возврата не указывает, какое именно значение будет возвращаться. Он указывает только тип этого значения.
Затем, внутри вызываемой функции, мы используем оператор return, чтобы указать возвращаемое значение — какое именно значение будет возвращаться обратно в caller.
Рассмотрим простую функцию, которая возвращает целочисленное значение:
Результат выполнения программы:
Первый вызов функции return7() возвращает 7 обратно в caller, которое затем передается в std::cout для вывода.
Третий вызов функции return7() опять возвращает 7 обратно в caller. Однако функция main() ничего с ним не делает, поэтому ничего и не происходит (возвращаемое значение игнорируется).
Примечание: Возвращаемые значения не выводятся на экран, если их не передать объекту std::cout. В последнем вызове функции return7() значение не отправляется в std::cout, поэтому ничего и не происходит.
Тип возврата void
Функции могут и не возвращать значения. Чтобы сообщить компилятору, что функция не возвращает значение, нужно использовать тип возврата void. Взглянем еще раз на функцию doPrint() из вышеприведенного примера:
Эта функция имеет тип возврата void, который означает, что функция не возвращает значения. Поскольку значение не возвращается, то и оператор return не требуется.
Вот еще один пример использования функции типа void:
Второй вызов функции returnNothing() даже не скомпилируется. Функция returnNothing() имеет тип возврата void, который означает, что эта функция не возвращает значения. Однако функция main() пытается отправить это значение (которое не возвращается) в std::cout для вывода. std::cout не может обработать этот случай, так как значения на вывод не предоставлено. Следовательно, компилятор выдаст ошибку. Вам нужно будет закомментировать эту строку, чтобы компиляция прошла успешно.
Возврат значений функцией main()
Почему нужно возвращать значения обратно в операционную систему? Дело в том, что возвращаемое значение функции main() является кодом состояния, который сообщает операционной системе об успешном или неудачном выполнении программы. Обычно, возвращаемое значение 0 (ноль) означает что всё прошло успешно, тогда как любое другое значение означает неудачу/ошибку.
Обратите внимание, по стандартам языка C++ функция main() должна возвращать целочисленное значение. Однако, если вы не укажете return в конце функции main(), компилятор возвратит 0 автоматически, если никаких ошибок не будет. Но рекомендуется указывать return в конце функции main() и использовать тип возврата int для функции main().
Еще о возвращаемых значениях
Во-вторых, когда процессор встречает в функции оператор return, он немедленно выполняет возврат значения обратно в caller и точка выполнения также переходит в caller. Любой код, который находится за оператором return в функции — игнорируется.
Функция может возвращать только одно значение через return обратно в caller. Это может быть либо число (например, 7 ), либо значение переменной, либо выражение (у которого есть результат), либо определенное значение из набора возможных значений.
Но есть способы обойти правило возврата одного значения, возвращая сразу несколько значений, но об этом детально мы поговорим на соответствующем уроке.
Наконец, автор функции решает, что означает её возвращаемое значение. Некоторые функции используют возвращаемые значения в качестве кодов состояния для указания результата выполнения функции (успешно ли выполнение или нет). Другие функции возвращают определенное значение из набора возможных значений. Кроме того, существуют функции, которые вообще ничего не возвращают.
Повторное использование функций
Одну и ту же функцию можно вызывать несколько раз, даже в разных программах, что очень полезно:
2.2 – Возвращаемые значения функций
Рассмотрим следующую программу:
Эта программа состоит из двух концептуальных частей: во-первых, мы получаем значение от пользователя. Затем мы сообщаем пользователю, чему равно это значение, умноженное на два.
Хотя эта программа достаточно тривиальна, и нам не нужно разбивать ее на несколько функций, но что, если бы мы захотели это сделать? Получение целочисленного значения от пользователя – это четко определенная задача, которую мы хотим, чтобы наша программа выполняла, поэтому она могла бы стать хорошим кандидатом на функцию.
Итак, давайте напишем программу для этого:
Хотя эта программа – хорошая попытка решения, она не совсем работает.
Возвращаемые значения
Когда вы пишете пользовательскую функцию, вы можете определить, будет ли ваша функция возвращать значение вызывающей стороне или нет. Чтобы вернуть значение вызывающей стороне, необходимы две вещи.
Давайте рассмотрим простую функцию, которая возвращает целочисленное значение, и пример программы, которая ее вызывает:
При запуске эта программа печатает:
В третьей инструкции функция returnFive вызывается снова, в результате чего значение 5 возвращается обратно вызывающей стороне. Однако функция main ничего не делает с возвращаемым значением, поэтому больше ничего не происходит (возвращаемое значение игнорируется).
Исправляем нашу тестовую программу
Теперь, узнав это, мы можем исправить программу, которую представили в начале урока:
Скомпилируйте эту программу и запустите ее несколько раз, чтобы убедиться, что она работает.
Отсутствие возвращаемого значения
Вот еще один пример функции, ничего не возвращающей, и пример программы, которая ее вызывает:
Возвращаясь к main
По определению, код состояния 0 означает, что программа выполнена успешно.
Лучшая практика
Ваша функция main должна возвращать 0, если программа работает нормально.
Код состояния, отличный от нуля, часто используется для обозначения сбоя (и хотя он отлично работает в большинстве операционных систем, строго говоря, его портируемость не гарантируется).
Для продвинутых читателей
EXIT_SUCCESS и EXIT_FAILURE определены в заголовочном файле :
На данный момент вы также должны определять свою функцию main внизу исходного файла кода, под другими функциями.
Несколько дополнительных замечаний о возвращаемых значениях
Лучшая практика
Предупреждение
Неспособность вернуть значение из функции с типом возврата не- void (кроме main ) приведет к неопределенному поведению.
В-третьих, функция может возвращать вызывающей функции при каждом вызове только одно значение. Однако это значение не обязательно должно быть литералом, оно может быть результатом любого допустимого выражения, включая переменную или даже вызов другой функции, которая возвращает значение. В приведенном выше примере getValueFromUser() мы вернули переменную, содержащую число, введенное пользователем.
Наконец, обратите внимание, что функция может определять, что означает ее возвращаемое значение. Некоторые функции используют возвращаемые значения как коды состояния, чтобы указать, были ли они успешными или неудачными. Другие функции возвращают вычисленное или выбранное значение. Остальные функции ничего не возвращают. Что возвращает конкретная функция, и смысл этого значения определяется автором функции. Из-за большого разнообразия возможностей рекомендуется задокументировать функцию комментарием, указывающим, что означают возвращаемые значения.
Повторное использование функций
Теперь мы можем проиллюстрировать хороший случай повторного использования функции. Рассмотрим следующую программу:
Пока эта программа работает, но она немного избыточна. Фактически, эта программа нарушает один из основных принципов хорошего программирования: «Не повторяйся» (или англоязычная аббревиатура DRY, т.е. «Don’t Repeat Yourself»).
Почему повторяющийся код плох? Если бы мы хотели изменить текст « Enter an integer: » на что-то другое, нам пришлось бы обновить его в двух местах. А что, если бы мы захотели инициализировать 10 переменных вместо 2? Это было бы большое количество избыточного кода (что сделало бы наши программы длиннее и сложнее для понимания) и много места для вкрадывания опечаток.
Эта программа создает следующий вывод:
В этом суть модульного программирования: возможность написать функцию, протестировать ее, убедиться, что она работает, а затем знать, что мы можем повторно использовать ее столько раз, сколько захотим, и она будет продолжать работать (пока мы не изменим эту функцию – после чего нам придется ее повторно протестировать).
Лучшая практика
Следуйте рекомендациям DRY: «не повторяйся». Если вам нужно сделать что-то более одного раза, подумайте, как изменить свой код, чтобы удалить как можно больше избыточности. Переменные можно использовать для хранения результатов вычислений, которые необходимо использовать более одного раза (чтобы нам не нужно было повторять вычисления). Функции можно использовать для определения последовательности инструкций, которые мы хотим выполнять более одного раза. А циклы (которые мы рассмотрим в следующей главе) можно использовать для выполнения инструкции более одного раза.
Заключение
Возвращаемые значения позволяют функциям возвращать одно значение обратно вызывающей функции.
Функции позволяют минимизировать избыточность наших программ.
Небольшой тест
Вопрос 1
Проверьте следующие программы и укажите, что они выводят, или будут ли они не компилироваться.
Эта программа печатает число 16.
Эта программа не компилируется. Вложенные функции не допускаются.
Эта программа компилируется, но ничего не выводит. Значения, возвращаемые функциями, ни для чего не используются (и, таким образом, отбрасываются).
Эта программа печатает буквы A и B в отдельных строках.
Эта программа не будет компилироваться, потому что функция имеет недопустимое имя. Мы говорили о правилах именования в уроке «1.7 – Ключевые слова и именование идентификаторов».
Эта программа будет скомпилирована, но функция не будет вызвана, потому что при вызове функции отсутствуют круглые скобки. То, что на самом деле будет выведено, зависит от компилятора.
Вопрос 2
Что означает «DRY» и почему это полезно?
DRY означает «Don’t Repeat Yourself» (не повторяйся). Это практика, которая включает в себя написание кода таким образом, чтобы минимизировать избыточность. Это делает ваши программы более краткими, менее подверженными ошибкам и более удобными для поддержки.