Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка DELPHI.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.73 Mб
Скачать

Рекурсия

Допускается, что подпрограмма может вызывать саму себя. Эта возможность связана с тем, что при каждом новом обращении к подпрограмме, параметры, которые она использует, заносятся в стек. Причем, параметры из стека удаляются при выходе из подпрограммы. Таким образом, в стеке сохраняются все параметры от предыдущих вызовов. В ряде случаев рекурсивное оформление подпрограммы более компактное и эффективное. Но не следует забывать, что существует опасность переполнения стека. Классическим примером рекурсии является рекурсивная формула вычисления факториала

N! = N(N-1)! (N-1)! = (N-1) (N-2)! и т.д.

Напишем подпрограмму вычисления факториала по рекурсивной формуле.

Function Factorial(N: byte): Cardinal;

Begin

If N in [0,1] then Result:=1

Else Factorial:=N*Factorial(N-1);

End;

При вычислении следует рассматривать прямой ход и обратный. В данном случае при прямом ходе в стек заносятся только данные. При обратном ходе происходят вычисления и удаляются параметры из стека.

Формальные и фактические параметры

Формальные параметры задаются при объявлении подпрограммы, фактические параметры указываются при выполнении расчетов, т.е. при вызове подпрограммы. Фактические параметры должны быть идентичных типов с формальными. Количество их должно быть равно количеству формальных параметров, должен совпадать и порядок следования фактических параметров с порядком записи формальных. Механизм передачи данных через формальные параметры реализуется, используя специальную область памяти – стек. По умолчанию размер стека установлен 16384 байта. Можно изменить объем стека в настройках среды Delphi.

Параметры-значения

В этом случае для передаваемого фактического параметра создаётся копия в стеке. Синтаксис записи, например, таков: Function FF(a,b:Real; …):…; (пример подпрограммы выше содержит этот тип параметров). На месте параметра-значения при вызове подпрограммы может стоять выражение, совместимое по присваиванию с формальным параметром. Внутри подпрограммы значение такого параметра измениться не может. Входные параметры можно задавать как параметры-значения. Передавать в подпрограмму массивы в виде параметров-значений нецелесообразно, т.к. расходуется лишняя память - в стеке создаётся дополнительная копия массива.

Параметры-переменные

При использовании в подпрограммах параметров-переменных в стеке выделяются ячейки для размещения адресов фактических параметров. В отличие от параметров-значений, внутри подпрограммы значения параметров-переменных могут изменяться. Так как фактические параметры в этом случае передаются по адресу, любое изменение параметра-переменной внутри подпрограммы, таким образом, фиксируется в фактическом параметре. Параметр-переменная записывается, используя ключевое слово var, например: Procedure PP(var c:Integer; …); (пример процедуры выше содержит этот тип параметра). Выходные параметры задаются как параметры-переменные.

Параметры-константы

Параметры-константы синтаксически введены для того, чтобы ключевое слово var сохранить за выходным параметром и в то же время входной параметр мог передаваться по адресу. Синтаксис записи этих параметров таков: Procedure PP(const a:real; …); (пример процедуры выше содержит этот тип параметра). В данном случае простые переменные передаются как копии, а, например, массивы и строки – по адресу. Компилятор сам определяет, что передавать по адресу, а что как копию. Изменить параметры-константы внутри подпрограммы нельзя. Таким образом, входные параметры могут передаваться в подпрограмму как параметры-константы. Вместо параметров-констант можно подставлять выражения, как и для параметров-значений.