Имена локальных и глобальных переменных могут совпадать.
4.3.8. Рекурсия
В Паскале подпрограммы могут обладать свойством рекурсии, то есть в ходе работы подпрограмма может вызывать сама себя. Различают 2 формы рекурсии: прямую и косвенную.
При прямой рекурсии процедура содержит оператор обращения к самой себе: При косвенной рекурсии одна процедура вызывает другую, которая сама либо посредством других процедур вызывает исходную процедуру: Рассмотрим примеры использования прямой рекурсии.
Program Factorial;
Var F,N:integer;
Procedure FACT(N:integer; Var F:integer);
begin
IF N=0 THEN F:=1
ELSE
begin
FACT(N-1,F); F:=N*F
end
end;
Begin
Write('Введите число= '); Readln(N);
FACT(N,F);
Writeln(F);
Readln
End.
В представленном выше примере рекурсивная процедура FACT вызывает сама себя до тех пор, пока не будет выполнено условие N=0. При каждом новом вызове процедуры FACT создается новое множество локальных переменных (формальных параметров-переменных “F”). Таким образом, рекурсивный вызов не изменяет переменные, расположенные вне вызываемой процедуры.
При выполнении правильно организованного рекурсивного блока осуществляется многократный последовательный переход от некоторого текущего уровня организации алгоритма к нижнему уровню до тех пор, пока не будет найдено условие, при котором рекурсия останавливается. В нашем примере рекурсия прекращается при N=0. Условие окончания работы рекурсивной процедуры должно находиться в самой процедуре, иначе произойдет зацикливание.
2. Распечатать в обратном порядке цифры положительного целого числа "N".
Procedure BackDigit (N:integer);
begin
Write(N mod 10);
IF (N div 10)<>0 THEN BackDigit(N div 10);
end;
mod - выделение остатка от частного;
div - выделение целой части частного.
Рекурсивный вызов может быть КОСВЕННЫМ:
Procedure A(x:integer);
begin
.............
B(x);
.............
end;
Procedure B(y:integer);
begin
.............
A(y);
.............
end;
При создании косвенной рекурсии возникает проблема: как описать вызываемую процедуру. Как известно, в Паскале все переменные, константы, метки, процедуры должны быть описаны до того, как будут упомянуты в операторах или выражениях, в противном случае компилятор объявит их имена неизвестными. В косвенной рекурсии процедура "А" вызывает процедуру "В", которая не описана. Выход из ситуации в следующем: используется опережающее описание с помощью директивы FORWARD. Эта директива объявляет только заголовок вызываемой процедуры, заменяя собой тело процедуры, откладывая описание содержимого (раздела операторов) на дальнейшее. Местоположение раздела операторов уже не играет роли, и в нем можно не указывать формальные параметры, а ограничиться лишь именем подпрограммы: