Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль_2.doc
Скачиваний:
6
Добавлен:
08.11.2018
Размер:
324.61 Кб
Скачать

Рекурсия

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

Пример Вычисление факториала

0!=1; 1!=1; n!=1*2*3… (n-1)*n n!=(n-1)!*n.

function Fact (n: word): longint;

begin

if n=1 then

Fact:=1

else

Fact:=n*Fact(n-1)

end;

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

Побочный эффект

Пример

program SideEffect;

var

a, z: integer;

function change(x: integer):integer;

begin

z:=z-x;

change: =sqr(x)

end;

begin

z:=10; a:=change(z);

writeln(a, z);

z:=10; a:=change(10)*change(z) {вызывается первым!!} writeln(a, z);

z:=10; a:=change(z)*change(10);

wrireln(a,z);

end.

Результат выполнения программы program SideEffect.

Вывод на экран

  1. 0

10000 -10

  1. 0

Анализ возможных вариантов работы программы представлен в таблице. Результат сравнения результатов анализа и результата работы программы program SideEffect показывают, что первым осуществляется вызов change(z), а затем change(10).

Непосредственное использование глобальных переменных в подпрограммах может привести к нежелательным изменениям их значений. Контроль за непосредственным использованием глобальных переменных в подпрограммах осуществляется программистом.

значения после

a

z

1 вызова

100

0

вывод на экран

100

0

возможный вариант

первым вызывается change(10)

2 вызова

100

0

3 вызова

0

0

вывод на экран

0

0

первым вызывается change(z)

2 вызова

100

0

3 вызова

100

-10

вывод на экран

10000

-10

возможный вариант

первым вызывается change(10)

4 вызова

100

0

5 вызова

0

0

вывод на экран

0

0

первым вызывается change(z)

4 вызова

100

0

5 вызова

100

-10

вывод на экран

10000

-10