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

C++: Возврат значений

Функции, которые мы определяли в предыдущих уроках, заканчивали свою работу тем, что печатали на экран какие-то данные:

void Greating() {
  std::cout << "Hello Code Basics!" << std::endl;
}


int main() {
  Greating();
  return 0;
}

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

В этом уроки мы рассмотрим, как сделать наши функции полезными.

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

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

Чтобы вернуть значение вызывающей стороне, необходимы две вещи:

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

Общий вид функции:

<тип возвращаемого значения> имя функции(аргументы) {
  return возвращаемое значение
}

Рассмотрим простую функцию, которая возвращает строку. Также пример программы, которая ее вызывает:

#include <iostream>
#include <string>
// функция возвращает строку, поэтому тип возвращаемого значения std::string
std::string GetDomain() {
  return "Hexlet"; 
}

int main() {
  std::cout << GetDomain() << std::endl;     // печатает Hexlet

  return 0;
}

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

Любой код после return не выполняется:

int sum() {
  return 2;
  std::cout << "Я никогда не выполнюсь";
}

Возвращать можно не только конкретное значение. Так как return работает с выражениями, справа от него может появиться почти все что угодно. Здесь нужно руководствоваться принципами читаемости кода:

#include <string>

std::string GetDomain() {
  std::string domain { "Hexlet" };
  return domain; 
}

Здесь мы не возвращаем переменную. Возвращается всегда значение, которое находится в этой переменной. Ниже пример с вычислениями:

int sum() {
  return 5 + 5;
}

Здесь сначала будет произведено вычисление, а затем результат мы вернем из функции.

Отсутствие возвращаемого значения

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

Посмотрим на функцию Greating():

#include <iostream>

void Greating() {
  std::cout << "Hello, Hexlet" << std::endl;
}

Эта функция имеет тип возвращаемого значения void. Это указывает на то, что она не возвращает значение вызывающей стороне.

Возврат значения из main

Теперь у нас есть концептуальные инструменты, чтобы понять, как работает функция main.

Когда программа выполняется, операционная система вызывает функцию main. Инструкции в main выполняются последовательно.

Также main возвращает целочисленное значение — обычно 0, и программа завершается. Значение, возвращаемое из main, называют кодом возврата. По нему судят об успешности выполнения программы.

Задание

Реализуйте функцию SayHurrayThreeTimes(), которая возвращает строку "hurray! hurray! hurray!".

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

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

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

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

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

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

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

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

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

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

Полезное


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