Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 75


| 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) }