Способы возврата значения из функции

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

Если функция не возвращает никакого значения, то вместо типа данных в объявлении и определении функции указывается ключевое слово void. Внутри такой функции оператора return может не быть, однако его можно использовать без указания значения для преждевременного выхода из функции. Вызов функции, не возвращающей никакого значения, нельзя размещать внутри какой-либо инструкции. Только в отдельной инструкции. Пример функции, которая не возвращает никакого значения:

void print(const char *s) {
   std::cout << s << std::endl;
}

В остальных случаях в объявлении и определении функции перед названием функции задается возвращаемый тип данных. Значение этого типа должно быть указано в операторе return. В этом случае возвращается копия значения. Функция может вернуть значение любого типа, кроме массива. Работать с массивами необходимо через параметры функции, передавая указатель на него, или возвращая указатель на конкретный элемент. Вызов функции, возвращающей какое-либо значение, можно разместить внутри выражения с правой стороны от оператора =. Если функция возвращает ссылку, то допускается размещение функции и с левой стороны от оператора =. Возвращаемое значение можно присвоить переменной или просто проигнорировать. Пример функции, возвращающей копию значения:

int sum(int x, int y) {
   return x + y;
}

При использовании оператора return не должно быть неоднозначных ситуаций. Например, в этом случае возвращаемое значение зависит от условия:

int sum(int x, int y) {
   if (x > 0) {
      return x + y;
   }
}

Если переменная x имеет значение больше нуля, то все будет нормально, но если переменная равна нулю или имеет отрицательное значение, то возвращаемое значение не определено и функция вернет произвольное значение, так называемый «мусор». В этом случае при компиляции выводится предупреждающее сообщение: warning: control reaches end of non-void function. Чтобы избежать подобной ситуации, следует в конце тела функции вставить оператор return со значением по умолчанию:

int sum(int x, int y) {
   if (x > 0) {
      return x + y;
   }
   return 0;
}

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

Листинг 12.22. Возврат указателя

#include <iostream>
#include <cstring>

char *func(char *s);

int main() {
   char *p = nullptr, str[] = "String";
   p = func(str);
   if (p) { // Если не нулевой указатель
      std::cout << *p << std::endl; // g
   }
   else std::cout << "nullptr" << std::endl;
   return 0;
}
char *func(char *s) {
   if (!s) return nullptr;
   size_t len = std::strlen(s); // Получаем длину строки
   if (!len) return nullptr;    // Нулевой указатель, если пусто
   else return &s[len - 1];     // Указатель на последний символ
}
Обратите внимание

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

Листинг 12.23. Возврат ссылки

#include <iostream>

int &at(int *a, int i);

int main() {
   int arr[] = {10, 20, 30};
   at(arr, 0) = 800;
   for (int i = 0; i < 3; ++i) {
      std::cout << at(arr, i) << ' ';
   } // 800 20 30
   std::cout << std::endl;
   return 0;
}
int &at(int *a, int i) {
   return a[i];
}
На заметку

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов