Процедура или функция может содержать вызов других процедур или
функций. В том числе процедура может вызвать саму себя. Никакого
парадокса здесь нет – компьютер лишь последовательно выполняет
встретившиеся ему в программе команды и, если встречается вызов
процедуры, просто начинает выполнять эту процедуру. Без разницы, какая
процедура дала команду это делать.
procedure Rec(a: integer ); begin if a> 0 then Rec(a- 1 ); writeln (a); end ; |
Рассмотрим, что произойдет, если в основной программе поставить вызов, например, вида Rec(3). Ниже представлена блок-схема, показывающая последовательность выполнения операторов.
Рис. 1. Блок схема работы рекурсивной процедуры.
Процедура Rec вызывается с параметром a = 3. В ней содержится вызов
процедуры Rec с параметром a = 2. Предыдущий вызов еще не завершился,
поэтому можете представить себе, что создается еще одна процедура и до
окончания ее работы первая свою работу не заканчивает. Процесс вызова
заканчивается, когда параметр a = 0. В этот момент одновременно
выполняются 4 экземпляра процедуры. Количество одновременно выполняемых
процедур называют глубиной рекурсии.
Четвертая вызванная процедура (Rec(0)) напечатает число 0 и закончит
свою работу. После этого управление возвращается к процедуре, которая ее
вызвала (Rec(1)) и печатается число 1. И так далее пока не завершатся
все процедуры. Результатом исходного вызова будет печать четырех чисел:
0, 1, 2, 3.
Еще один визуальный образ происходящего представлен на рис. 2.
Рис. 2. Выполнение процедуры Rec с параметром 3 состоит из выполнения процедуры Rec с параметром 2 и печати числа 3. В свою очередь выполнение процедуры Rec с параметром 2 состоит из выполнения процедуры Rec с параметром 1 и печати числа 2. И т. д.
В качестве самостоятельного упражнения подумайте, что получится при
вызове Rec(4). Также подумайте, что получится при вызове описанной ниже
процедуры Rec2(4), где операторы поменялись местами.
procedure Rec2(a: integer ); begin writeln (a); if a> 0 then Rec2(a- 1 ); end . |
Обратите внимание, что в приведенных примерах рекурсивный вызов стоит внутри условного оператора. Это необходимое условие для того, чтобы рекурсия когда-нибудь закончилась. Также обратите внимание, что сама себя процедура вызывает с другим параметром, не таким, с каким была вызвана она сама. Если в процедуре не используются глобальные переменные, то это также необходимо, чтобы рекурсия не продолжалась до бесконечности.
Комментариев нет:
Отправить комментарий