Читаем Язык программирования C++. Пятое издание полностью

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

Для примера вернемся к функции error_msg из раздел 6.2.6. Эта функция получала переменное количество строковых аргументов и выводило сообщение об ошибке, составленное из переданных строк. Теперь вместо вызова функции error_msg() мы возвратим вектор, содержащий строки сообщений об ошибке:

vector process() {

 // ...

 // expected и actual - строки

 if (expected.empty())

  return {}; // возвратить пустой вектор

 else if (expected == actual)

  return {"functionX", "okay"}; // возвратить вектор

                                // инициализированный списком

 else

  return {"functionX", expected, actual};

}

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

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

Возвращение значения из функции main()

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

Как упоминалось в разделе 1.1, значение, возвращаемое из функции main(), рассматривается как индикатор состояния. Возвращение нулевого значения означает успех; большинство других значений — неудачу. У значения, отличного от нуля, есть машинно-зависимое значение. Чтобы сделать его независимым от машины, заголовок cstdlib определяет две переменные препроцессора (см. раздел 2.3.2), которые можно использовать для индикации успеха или отказа:

int main() {

 if (some failure)

  return EXIT_FAILURE; // определено в cstdlib

 else

  return EXIT_SUCCESS; // определено в cstdlib

}

Поскольку это переменные препроцессора, им не должна предшествовать часть std:: и их нельзя использовать в объявлениях using.

Рекурсия

Функция, которая вызывает себя прямо или косвенно, является рекурсивной функцией (recursive function). В качестве примера можно переписать функцию вычисления факториала так, чтобы использовать рекурсию:

// вычислить val!, т.е. 1 * 2 * 3 ... * val

int factorial(int val) {

 if (val > 1)

  return factorial(val-1) * val;

 return 1;

}

В этой реализации осуществляется рекурсивный вызов функции factorial(), чтобы вычислить факториал числа, начиная со значения, первоначально переданного val, и далее в обратном порядке. Когда значение val достигнет 1, рекурсия останавливается и возвращается значение 1.

В рекурсивной функции всегда должно быть определено условие выхода или останова (stopping condition); в противном случае рекурсия станет бесконечной, т.е. функция продолжит вызывать себя до тех пор, пока стек программы не будет исчерпан. Иногда эта ошибка называется бесконечной рекурсией (infinite recursion). В случае функции factorial() условием выхода является равенство значения параметра val единице.

Ниже приведена трассировка выполнения функции factorial() при передаче ей значения 5.

Трассировка вызова функции factorial(5)

ВызовВозвращаетЗначение
factorial(5)factorial(4) * 5120
factorial(4)factorial(3) * 424
factorial(3)factorial(2) * 36
factorial(2)factorial(1) * 22
factorial(1)11

Функция main() не может вызывать сама себя.

Упражнения раздела 6.3.2

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

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных