| TYPE
ProcType = procedure ( А, В : Real; VAR X : Real;
f : RealFunctionType );
а тип процедуры без параметров:
NoParamProcType = procedure;
После объявления процедурного (функционального) типа его можно использовать в описаниях параметров подпрограмм. И, ко-
- 115 -
нечно, необходимо написать те реальные процедуры и функции, которые будут передаваться как параметры. Требование к ним одно: они должны компилироваться в режиме {$F+}. Поскольку по умолчанию принят режим {$F-}, такие процедуры обрамляются парой соответствующих директив. На рис. 6.11 дан пример функции, принадлежащей введенному выше типу RealFunctionType.
| >{ $F+} { включение режима $F+ }
| >FUNCTION SinExp ( tt : Real ) : Real;
| BEGIN
| >SinExp := Sin(tt)*Exp(tt)
| END;
| >{$F-} { восстановление режима по умолчанию }
Рис. 6.11
Такая функция может быть подставлена в вызов подпрограммы на рис. 6.10:
Integral( 0, 1, Res1, SinExp )
и мы получим в переменной Res1 значение интеграла в пределах [0,1]. Не всякую функцию (процедуру) можно подставить в вызов. Нельзя подставлять: во-первых, процедуры с директивами inline и interrupt (из-за особенностей их машинного представления); во-вторых, вложенные процедуры или функции; в-третьих, стандартные процедуры и функции, входящие в системные библиотеки Турбо Паскаля. Нельзя, например, взять интеграл функции синуса:
Integral(0, 1, Res2, Sin)
хотя встроенная функция Sin внешне подходит по типу параметра. Последнее ограничение легко обходится переопределением функции (рис. 6.12).
| >{ $F+}
| >FUNCTION Sin2( X : Real ) : Real;
| BEGIN
| >Sin2 := Sin( X )
| END;
| >{$F-}
Рис. 6.12
- 116 -
Теперь вызов процедуры интегрирования переписывается как
Integral( 0, 1, Res2, Sin2 )
Применение процедурного типа не ограничивается одним лишь описанием параметров-процедур или функций. Раз есть такой тип, то могут быть и переменные такого типа.
6.9.5. Переменные-процедуры и функции
Рассмотрим программу на рис. 6.13. В ней вводятся две переменные-процедуры P1 и P2 и демонстрируются возможные действия с ними.
| >TYPE DemoProcType = procedure ( А,В : Word );
| VAR
| >Р1, Р2 : DemoProcType; { переменные-процедуры} P : Pointer; { просто указатель }
| >{ Значения переменных-процедур : }
| > {$F+}
| PROCEDURE Demo1( X,Y : Word );
| BEGIN WriteLn( 'x+y=', x+y ) END;
| PROCEDURE Demo2( X,Y : Word );
| BEGIN WriteLn( 'x-y=', x-y ) END;
| > {$F-}
| BEGIN { основной блок программы }
| > P1 := Demo1; { присваивание значений переменным }
| > P2 := Demo2;
| > P1( 1, 1 ); { то же самое, что и вызов Demo1(1,1) }
| > P2( 2, 2 ); { то же самое, что и вызов Demo2(2,2) }