Рекурсия
Из инструкций внутри функции разрешено вызывать эту же функцию. Такие вызовы называются рекурсивными.
Вернемся к примеру с вычислением чисел Фибоначчи. Следуя формуле расчета каждого числа как суммы двух предыдущих (за исключением двух первых, которые равны 1), легко написать рекурсивную функцию расчета чисел Фибоначчи.
int Fibo(const int n)
|
В рекурсивной функции должен быть предусмотрен возврат управления без рекурсии, как в нашем случае внутри уловного оператора if для индексов 0 и 1. Иначе последовательность вызовов функции могла бы продолжаться бесконечно. На практике, поскольку незавершенные вызовы функции накапливаются в ограниченной области памяти под названием стек (см. раздел Инструкции объявления/определения, а также врезку "Куча"и "стек" в разделе Описание массивов), рано или поздно она закончится с ошибкой времени выполнения "Переполнения стека" ("Stack overflow"). Эта проблема продемонстрирована в функции FiboEndless.
int FiboEndless(const int n)
|
Обратите внимание, это не ошибка компиляции. Компилятор в данном случае не поможет даже предупреждением (хотя теоретически мог бы). Ошибка возникнет в процессе исполнения скрипта и будет выведена в журнал Экспертов в терминале.
Рекурсия может возникать не только при непосредственном вызове функции из неё самой. Например, если функция F вызывает функцию G, а та, в свою очередь, функцию F, то это тоже рекурсия, хоть и опосредованная. Таким образом, возможна рекурсия при цикличности вызовов любого порядка (глубины).