**
*******
**
* * *
* * *
Прямая рекурсия
Рассмотренные выше программы использовали так называемую прямую рекурсию, когда в теле некоторой процедуры содержался непосредственный вызов самой себя.
Косвенная рекурсия
Вязыке Паскаль допускается также и косвенная рекурсия, когда, например, процедура, процедура А вызывает процедуру В, а та, в свою очередь,- процедуру А. Длина таких цепочек вызовов может быть произвольной, однако при разработке программы необходимо тщательно следить за тем, чтобы рекурсивный алгоритм был сходимым, то есть не приводил к бесконечным взаимным вызовам подпрограмм.
Пример 1.9. Программа иллюстрирует косвенные рекурсивные вызовы процедур. В этой программе процедуры Rec1 и Rec2 рекурсивно вызывают друг друга, поочередно уменьшая свои фактические параметры. Обе процедуры работают с одной глобальной переменной А, которая передается в них по ссылке. Критерием завершения работы является обращение этой переменной
вноль.
Впрограмме необходимо предварительное определение второй процедуры Rec2, так как ее вызов встречается в процедуре Rec1, т.е. перед ее
полным описанием.
Program KosvRecurs; Var A : integer;
Procedure Rec2 (Var Y:integer); Forward1;
1Опережающее объявление
Внекоторых ситуациях возникает необходимость вызвать подпрограмму, описанную далее по тексту программы. Например, эта необходимость возникает при косвенной
рекурсии (подпрограмма A вызывает подпрограмму B, а та в свою очередь вызывает
10
Procedure Rec1 (Var X:integer); Begin
X := X-1;
if X>0 then Begin
writeln (‘X=’,X); Rec2(X)
End
End;
Procedure Rec2 (Var Y:integer); Begin
Y := Y div 2; if Y>2 then
Begin
writeln (‘Y=’,Y); Rec1(Y)
End
End;
Begin
A := 15;
Rec1(A); writeln (‘A=’,A)
End.
Что будет напечатано на экране? Ответ:
X=14
Y=7
X=6
Y=3
X=2
A=1
подпрограмму A). В этом случае используется опережающее объявление подпрограммы, состоящее из ее заголовка, за которым следует служебное слово forward.
Например:
procedure B(i: integer); forward;
Запрещено делать опережающее объявление для уже описанной подпрограммы.
11