Урок №12. Функции и оператор возврата return



Книга Урок №12. Функции и оператор возврата return

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

Функции

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

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

Метод, в котором происходит вызов, известен как caller, а функция, которую вызывают - вызываемая функция, например:

#include // для std::cout и std::endl

// Объявление функции doPrint(), которую мы будем вызывать

void doPrint ( ) {

std :: cout << "In doPrint()" << std :: endl ;

}

// Объявление функции main()

int main ( )

{

std :: cout << "Starting main()" << std :: endl ;

doPrint ( ) ; // прерываем выполнение функции main() вызовом функции doPrint(). Функция main() в данном случае является caller-ом

std :: cout << "Ending main()" << std :: endl ;

return 0 ;

}

Результат работы программы:

Starting main()
In doPrint()
Ending main()

Программа начинает свою работу с вызова функции main(), где на экран выводится фраза: "Starting main()". Далее в функции main() выполняется вызов функции doPrint(). После этого выполнение кода в функции main() приостанавливается, и процессор переходит к выполнению кода внутри функции doPrint(). Единственная строка в функции doPrint() выводит сообщение "In doPrint()". По завершении работы функции doPrint() процессор возвращается обратно в функцию main() и продолжает выполнение кода с того места, где была остановка. Следовательно, следующей строкой будет вывод "Ending main()".

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

Не забывайте при вызове функций использовать круглые скобки ().

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

После завершения работы функции main() она передает целочисленное значение обратно в операционную систему с помощью оператора return.

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

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

Давайте изучим элементарную функцию, которая возвращает целочисленный результат:

#include

// int означает, что функция возвращает целочисленное значение обратно в caller

int return7 ( )

{

// Эта функция возвращает целочисленное значение, поэтому мы должны использовать оператор return

return 7 ; // возвращаем число 7 обратно в caller

}

int main ( )

{

std :: cout << return7 ( ) << std :: endl ; // выведется 7

std :: cout << return7 ( ) + 3 << std :: endl ; // выведется 10

return7 ( ) ; // возвращаемое значение 7 игнорируется, так как функция main() ничего с ним не делает

return 0 ;

}

Результат работы программы:

7
10

Давайте рассмотрим более подробно:

Обратите внимание: Если не передать возвращаемые значения объекту std::cout, они не будут отображаться на экране. В случае с последним вызовом функции return7() значение не передается в std::cout, поэтому ничего не происходит.

Тип возврата void

Функции могут не возвращать результат. Для указания компилятору, что функция не возвращает значение, следует использовать тип void в качестве возвращаемого значения. Рассмотрим функцию doPrint() из предыдущего примера:

void doPrint ( ) // void - это тип возврата

{

std :: cout << "In doPrint()" << std :: endl ;

// Эта функция не возвращает никакого значения, поэтому оператор return здесь не нужен

}

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

Вот пример, демонстрирующий работу функции типа void:

Для включения библиотеки iostream используется директива #include.

// void означает, что функция не возвращает значения

void returnNothing ( )

{

std :: cout << "Hi!" << std :: endl ;

// Эта функция не возвращает никакого значения, поэтому оператор return здесь не нужен

}

int main ( )

{

returnNothing ( ) ; // функция returnNothing() вызывается, но обратно в main() ничего не возвращает

std :: cout << returnNothing ( ) ; // ошибка, эта строчка не скомпилируется. Вам нужно будет её закомментировать

return 0 ;

}

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

При втором вызове функции returnNothing() даже не будет компилироваться. Функция returnNothing() возвращает тип void, что означает, что она не возвращает никакого значения. Однако функция main() пытается вывести это значение (которое отсутствует) в std::cout для вывода. std::cout не может обработать этот случай, поскольку значение для вывода не предоставлено. Поэтому компилятор выдаст ошибку. Чтобы успешно скомпилировать программу, вам нужно будет закомментировать эту строку.

Возврат значений обратно в функцию main()

Теперь вы понимаете, как работает функция main(). При запуске программы операционная система вызывает функцию main() и начинается ее выполнение. Все операторы внутри main() выполняются поочередно. По завершении работы функция main() возвращает целочисленное значение (обычно 0) обратно в операционную систему. Поэтому функция main() объявляется как int main().

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

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

Еще о возвращаемых значениях

Во-первых, если функция не имеет тип void, то она должна возвращать значение этого типа с помощью оператора return. Единственным исключением является функция main(), которая возвращает 0, если не указано другое значение.

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

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

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

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

Повторное использование функций

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

#include

// Функция getValueFromUser() получает значение от пользователя, а затем возвращает его обратно в caller

int getValueFromUser ( )

{

std :: cout << "Enter an integer: " ;

int x ;

std :: cin >> x ;

return x ;

}

int main ( )

{

int a = getValueFromUser ( ) ; // первый вызов функции getValueFromUser()

int b = getValueFromUser ( ) ; // второй вызов функции getValueFromUser()

std :: cout << a << " + " << b << " = " << a + b << std :: endl ;

return 0 ;

}

Результат работы программы:

Enter an integer: 4
Enter an integer: 9
4 + 9 = 13

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

Кроме того, main() не является единственной функцией, способной вызывать другие функции. Любая функция имеет возможность вызвать любую другую функцию!

#include

void printO ( )

{

std :: cout << "O" << std :: endl ;

}

void printK ( )

{

std :: cout << "K" << std :: endl ;

}

// Функция printOK() вызывает как printO(), так и printK()

void printOK ( )

{

printO ( ) ;

printK ( ) ;

}

// Объявление main()

int main ( )

{

std :: cout << "Starting main()" << std :: endl ;

printOK ( ) ;

std :: cout << "Ending main()" << std :: endl ;

return 0 ;

}

Результат работы программы:

Starting main()
O
K
Ending main()

Вложенные функции

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

#include

int main ( )

{

int boo ( ) // эта функция находится внутри функции main(), что запрещено

{

std :: cout << "boo!" ;

return 0 ;

}

boo ( ) ;

return 0 ;

}

Вот как нужно делать правильно:

#include

int boo ( ) // теперь уже не в main()

{

std :: cout << "boo!" ;

return 0 ;

}

int main ( )

{

boo ( ) ;

return 0 ;

}

Тест

Какие из перечисленных программ не будут скомпилированы (и почему), а какие будут скомпилированы (и какой будет результат)?

Первая программа:

Необходимо добавить библиотеку iostream.

int return5 ( )

{

return 5 ;

}

int return8 ( )

{

return 8 ;

}

int main ( )

{

std :: cout << return5 ( ) + return8 ( ) << std :: endl ;

return 0 ;

}

Вторая программа:

#include

int return5 ( )

{

return 5 ;

int return8 ( )

{

return 8 ;

}

}

int main ( )

{

std :: cout << return5 ( ) + return8 ( ) << std :: endl ;

return 0 ;

}

Третья программа:

include

int return5 ( )

{

return 5 ;

}

int return8 ( )

{

return 8 ;

}

int main ( )

{

return5 ( ) ;

return8 ( ) ;

return 0 ;

}

Четвертая программа:

include

void printO ( )

{

std :: cout << "O" << std :: endl ;

}

int main ( )

{

std :: cout << printO ( ) << std :: endl ;

return 0 ;

}

Пятая программа:

include

int getNumbers ( )

{

return 6 ;

return 8 ;

}

int main ( )

{

std :: cout << getNumbers ( ) << std :: endl ;

std :: cout << getNumbers ( ) << std :: endl ;

return 0 ;

}

Шестая программа:

include

int return 6 ( )

{

return 6 ;

}

int main ( )

{

std :: cout << return 6 ( ) << std :: endl ;

return 0 ;

}

Седьмая программа:

include

int return6 ( )

{

return 6 ;

}

int main ( )

{

std :: cout << return6 << std :: endl ;

return 0 ;

}

Просим оставить свой ответ в комментариях ниже!

Важно помнить, что перед использованием "include" необходимо добавить решётку. К сожалению, на платформе Яндекс.Дзен ограничено количество решёток, которые можно использовать.

163   0  

Comments

    Ничего не найдено.