X0,xn,xh,ym:real;
PROCEDURE F1(A0,AN,AH:REAL;M:INTEGER;VAR F:MASSIV);FAR;
{задание массива значений функции F1}
BEGIN
. . .
END;
PROCEDURE F2(A0,AN,AH:REAL;M:INTEGER;VAR F:MASSIV);FAR;
{задание массива значений функции F2}
BEGIN
. . .
END;
FUNCTION MIN(A0,AN,AH:REAL;M:INTEGER;FUN:PROC):REAL;
VAR
F1:MASSIV;
MINF:REAL;
K:INTEGER;
BEGIN
FUN(A0,AN,AH,M,F1);
MINF:=F1[1];
FOR K:=2 to M DO
IF F1[K]<MINF THEN MINF:=F1[K];
MIN:=MINF;
END;
BEGIN {основная программа}
X0:=1; XN:=10; XH:=1;
YM:=MIN(X0,XN,XH,N,F1);
WRITELN('минимум функции Y1=',YM:4:2);
YM:=MIN(X0,XN,XH,N,F2);
WRITELN('минимум функции Y2=',YM:4:2);
END.
Процедуры и функции в Турбо-Паскале могут быть рекурсивными, если они вызывают сами себя. При этом требуется особым образом организовать вычислительный процесс, так как при рекурсивных вычислениях необходимо сохранение информации об иерархии связей и локальных переменных всех рекурсивных вызовов, чтобы по окончании цепочки рекурсивных вызовов можно было восстановить каждое предшествующее прерванное состояние программы. Рекурсивный вызов процедурой саму себя можно считать аналогом прерывания, только программа обработки прерывания всегда одна и та же. При этом практически всегда используется стековая память. Стеком называют область памяти с последовательным доступом, работающую по принципу “Последним пришел – первым вышел”. Классическим примером рекурсии является вычисление факториала.
FUNCTION FACT (N:INTEGER):INTEGER;
BEGIN
IF N=1 THEN FACT:=1
ELSE FACT:=N*FACT(N-1);
END.
Использование рекурсивных процедур и функций делает программу более наглядной, чем при организации итерационных циклов. Однако довольно часто рекурсии оказываются более медленными и могут вызвать переполнение стека, т.к. при каждом входе в подпрограмму, её локальные переменные размещаются в стеке. Рекурсии рекомендуется применять только там, где нет очевидного итерационного решения.
Если процедура непосредственно вызывает саму себя, то такая рекурсия называется простой рекурсией. Возможна ситуация, когда процедура вызывает одну или несколько промежуточных процедур, которые в свою очередь вызывают первую процедуру. Такая рекурсия называется косвенной. При таком взаимном обращении процедур друг к другу нет возможности выполнить необходимое правило, что все процедуры и функции должны быть описаны до их вызова. В этом случае используется опережающее описание процедур и функций. Записывается только заголовок процедуры, за которым ставится слово FORWARD, описание же текста процедуры помещается далее в любом месте раздела описания процедур. При этом не повторяется список формальных параметров.
PROGRAM PRIMER;
VAR
A,B:REAL;
PROCEDURE P(X:REAL);FORWARD;
PROCEDURE R(Y:REAL);
BEGIN
…
P(A);
…
END;
PROCEDURE P;
BEGIN
R(B);
END;
BEGIN {основная программа}
…
R(A); P(B);
…
END.
