C++: Определение функций
У каждой программы должна быть функция с именем main
. С нее программа начинает выполняться при запуске. Но когда программа масштабируется, становится сложнее размещать весь код внутри этой функции. В этом случае используют функции, которые позволяют разделить программы на небольшие модульные части. Их легче организовать, тестировать и использовать.
Большинство программ используют множество функций. Стандартная библиотека C++ поставляется с множеством уже написанных функций, которые вы можете использовать, но также часто можно писать и свои собственные. Функции, которые вы пишете сами, называются пользовательскими функциями.
В этом уроке мы рассмотрим как создавать пользовательские функции.
Что такое функция
Представим, что мы читаем книгу и вспоминаем, что нам нужно сделать звонок. Мы оставляем закладку, говорим по телефону и возвращаемся читать книгу с того места, где оставили закладку.
Программы на C++ могут работать так же. Программа будет последовательно выполнять инструкции внутри одной функции, пока не обнаружит вызов другой функции.
Вызов функции — это выражение, которое говорит CPU прервать текущую функцию и выполнить другую. Получается, что CPU «помещает закладку» в текущую точку выполнения, а затем вызывает функцию, указанную в вызове функции. Когда вызываемая функция завершается, CPU возвращается в точку, которая отмечена закладкой, и возобновляет выполнение.
Разберемся как определять пользовательские функции в С++.
Структура функции
Начнем с базового синтаксиса для определения пользовательской функции. В этом уроке все пользовательские функции кроме main
будут иметь следующий вид:
тип_возвращаемого_значения идентификатор(параметры функции) { // идентификатор заменяется именем вашей функции
// ваш код здесь
}
Подробнее о различных частях этого синтаксиса поговорим в следующих уроках. На данный момент идентификатор будет просто заменен именем нашей пользовательской функции. Фигурные скобки и инструкции между ними называются телом функции.
Рассмотрим пример программы, которая показывает, как определяется и вызывается новая функция:
void Greating() {
std::cout << "Hello Code Basics!" << std::endl;
}
int main() {
std::cout << "Starting main()" << std::endl;
// Прерываем main(), вызывая функцию Greating().
Greating();
// эта инструкция выполняется после завершения Greating()
std::cout << "Ending main()" << std::endl;
return 0;
}
Эта программа создает следующий вывод:
Starting main() Hello Code Basics! Ending main()
Программа начинает выполняться с начала функции main
. Первая строка, которая будет выполняться, выводит текст Starting main()
. Вторая строка в main
— это вызов функции Greating()
. Мы вызываем функцию Greating()
, добавляя скобки к имени функции, например: Greating()
. Если забыть про скобки, программа может не компилироваться.
Так как мы вызвали функцию, выполнение инструкций в main
приостанавливается. В итоге выполнение переходит к началу вызываемой функции Greating()
.
Первая и единственная строка в Greating()
печатает текст Hello Code Basics!
. Когда Greating()
завершается, выполнение возвращается к вызывающей функции — здесь: функция main
. Далее оно возобновляется с того места, где остановилось. Получается, следующая инструкция, которая выполняется в main
, выводит на печать Ending main()
.
Особенность функций
Полезная особенность функций заключается в том, что их можно вызывать более одного раза в разных частях программы. Вот программа, которая демонстрирует это:
void Greating() {
std::cout << "Hello Code Basics!" << std::endl;
}
int main() {
Greating();
Greating();
return 0;
}
Обратите внимание мы вызываем функцию Greating()
два раза.
Эта программа создает следующий вывод:
Hello Code Basics! Hello Code Basics!
В отличие от некоторых других языков программирования в C++ функции не могут быть определены внутри других функций. Следующая программа не является корректной:
int main() {
void Greating() {
std::cout << "Hello Code Basics!";
}
Greating();
return 0;
}
В коде выше мы попытались определить внутри функции main()
, функцию Greating()
и получили ошибку компиляции:
main.cpp:12:3: error: ‘PrintMoto’ was not declared in this scope 12 | PrintMoto(); | ^~~~~~~~~
Это прежде всего связанно с особенностью языка и выделением памяти.
В этом уроке мы рассмотрели структуру и создание функций. Понятие «создать функцию» имеет много синонимов: «реализовать», «определить» и даже «заимплементить» (от слова implement). Все они встречаются в повседневной практике на работе.
Задание
Напишите функцию PrintMoto()
, которая выводит на экран фразу Spring is coming
, и вызовите ее внутри функции main
.
Упражнение не проходит проверку — что делать? 😶
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя 🤔
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно 🙄
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.