Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты на зачет.docx
Скачиваний:
51
Добавлен:
01.06.2015
Размер:
554.66 Кб
Скачать

Рекурсивные процедуры

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

Каждое обращение к процедуре вызывает независимую активацию этой процедуры. Совокупность всех данных, необходимых для одной активации процедуры, называется фреймом активации. Фреймы активации содержат независимые копии всех локальных переменных и формальных параметров процедуры, в которых оставляют «следы» своей деятельности операторы текущей активации. Если процедура обращается к себе несколько раз, образуется несколько параллельно (одновременно) существующих активаций. При этом, каждая активация характеризуется своим фреймом активации (все они являются различными экземплярами одной и той же структуры).

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

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

Существует целый класс структур данных, для которых рекурсивные процедуры представляют собой наиболее удобный способ обработки. Примером такой организации является дерево.

Итерация и рекурсия

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

Произвольный цикл WHILE

Эквивалентная рекурсивная процедура

WHILE УсловиеЦикла DO ТелоЦикла END;

PROCEDURE РекурсивныйЦикл; BEGIN IF УсловиеЦикла THEN ТелоЦикла; РекурсивныйЦикл END END РекурсивныйЦикл

Каждая реализация процедуры РекурсивныйЦикл эквивалентно одному из повторений цикла WHILE. Если условие цикла истинно, то перед рекурсивным обращением к процедуре РекурсивныйЦикл выполняется тело цикла. Таким образом, процедура РекурсивныйЦикл рекурсивно вызывает себя, моделируя следующую итерацию цикла.

Если при обращении к процедуре РекурсивныйЦикл условие цикла оказалось ложным, то процедура (точнее, каждая из ее активаций, начиная с самой последней) немедленно завершается. Как только одна из активаций завершается, завершаются и все предыдущие активации. Это происходит потому, что рекурсивное обращение к процедуре расположено в самом конце этой процедуры.

Существует два важных математических (и программистских) результата, обобщающих отношение между рекурсией и итерацией:

  1. Каждый итеративный цикл может быть заменен рекурсией.

  2. Рекурсия не всегда может быть заменена итерацией

Рекурсия – это мощное средство, позволяющее строить элегантные и выразительные алгоритмы. Однако, рекурсивные алгоритмы могут вызывать значительные сложности при отладке. Казалось бы, незначительные ошибки в логике рекурсивных алгоритмов часто приводят к катастрофическим последствиям во время их выполнения. Бесконечная рекурсия – одна из наиболее часто встречающихся проблем в этой области. Бесконечная рекурсия образуется в случае, когда процедуры или функции рекурсивно вызывают сами себя бесконечное число раз (то есть, они не могут выйти на завершающую ветвь).

Предположим, что два оператора, находящиеся в ветви THEN процедуры РекурсивныйЦикл, просто переставлены местами. Хотя модифицированная процедура выглядит весьма похоже на корректную, в этом случае тело цикла «не успевает» изменить переменные, от которых зависит тело цикла, вследствие чего, условие цикла постоянно истинно при всех обращениях.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]