Бесплатный курс по C++. Зарегистрируйтесь для отслеживания прогресса →

C++: Определение функций

Вы уже знаете, что каждая программа должна иметь функцию с именем main (именно отсюда программа начинает свое выполнение при запуске). Однако по мере того, как программы становятся всё длиннее и длиннее, становится всё труднее управлять размещением всего кода внутри функции 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;
}

Эта программа создает следующий вывод:

  Hello Code Basics!
  Hello Code Basics!

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

int main() {
  void Greating() {
    std::cout << "Hello Code Basics!";
  }
  Greating();
  return 0;
}

Задание

Напишите функцию PrintMoto() которая выводит на экран фразу Spring is coming и вызовите ее внутри функции main.

Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

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

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Полезное


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе