Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник_Часть_1.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
974.85 Кб
Скачать

Var f : longint ;

Function fact ( f : inteqer ) : longint ;

{описание функции, f – формальный параметр, значение типа inteqer, результат функции – типа longint}

begin

if f = 0

then fact : = 1

else fact : = f * fact (f - 1)

end;

begin

write (Введите число f > 0 ') ;

readln (f) ;

if f > 0

then writeln('Для числа ' ,N,' значение фак-

ториала = ' , fact(f) )

else writeln(' число неверное ! ' ) ;

end.

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

Вызов процедурой самой себя (рекурсивный вызов) ничем не отличается от вызова другой процедуры.

Что происходит, если одна процедура (или программа) вызывает другую? В общих чертах происходит следующее:

1) в памяти размещаются параметры, передаваемые процедуре (но не параметры-переменные);

2) в другом месте памяти сохраняются значения внутренних переменных вызывающей процедуры;

3) запоминается адрес возврата в вызывающую процедуру (или программу);

4) управление передается вызванной процедуре.

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

П р и м е р. Пусть рекурсивная функция step(a : real ; n : inteder) : real ; возводит число a в степень n (a n). Вычислить Z = Xk + Ym.

Program rec_2;

Var a, y, z : real;

k, m : integer;

function step ( a: real ; n : integer) : real;

begin

if n = 0

then step : = 1

else step : = a step (a, N -1)

end;

begin

readln (x , k);

readln (y, m);

z := step (x, k) + step (y, m);

writeln(z:0:3)

end.

Возникает вопрос: «Можно ли использовать рекурсивные процедуры с бесконечным «самовызовом» Нет, так как не существует бесконечной памяти!

П р и м е р. {Бесконечная рекурсия}

program smile;

procedure PopandDog;

beqin

writeln (' У попа была собака, он ее любил ') ;

writeln (' она съела кусок мяса, он ее убил ' ) ;

writeln ( ' похоронил и надпись написал: ' ) ;

PopeandDog;

end;

beqin

PopandDog

end.

Внесем небольшие изменения в программу.

{Правильная рекурсия}

program smile;

procedure PopandDog(k : inteqer);

beqin

writeln (' У попа была собака, он ее любил ') ;

writeln (' она съела кусок мяса, он ее убил ' ) ;

writeln ( ' похоронил и надпись написал: ' ) ;

if k > 1

then popeand Dog ( k - 1) ;

end ;

beqin

PopandDog( 5 )

end.

Следовательно, условие, по которому выполняется вызов процедуры, должно на некотором уровне рекурсии стать ложным.

Пока условие истинно, рекурсивный спуск продолжается. Когда условие становится ложным, спуск заканчивается и начинается поочередный рекурсивный возврат из всех вызванных на данный момент копий рекурсивной процедуры.