Глава 8. ПРОЦЕДУРНЫЕ ТИПЫ
В Turbo Pascal процедуры и функции можно рассматривать как некоторые параметры и можно
использовать переменные, принимающие значение процедуры или функции. С этой целью вводятся
процедурные типы, которые указывают, какой вид подпрограммы (процедуру или функцию) можно
использовать в качестве параметра и с какими параметрами должны быть эти подпрограммы.
Объявление процедурного типа похоже на заголовок подпрограммы (см. п. 10): пишется слово
procedure или function, за которым в круглых скобках записывается список формальных
параметров; для функции после списка формальных параметров через двоеточие указывается тип
функции. В отличие от заголовка подпрограммы здесь не указывается имя подпрограммы.
Пример.
type
Procl = procedure; {процедура без параметров}
Proc2 = procedure(var X,Y: Integer);
{процедура с двумя параметрами-переменными целого типа}
Funct = function(X: Real): Real;
{функция вещественного типа с одним параметром—значением}
Далее можно ввести переменные этих типов:
var
P1: Procl;
Р2: Proc2;
F1: Funct;
После этого процедурным переменным можно присваивать значения конкретных процедур и
функций. Как и во всех других случаях, процедурная переменная и подпрограмма должны быть
совместимы для присваивания (т. е. должны иметь одинаковое число формальных параметров,
совпадающих по типам; функции, кроме того, должны иметь идентичный тип).
Существует ряд правил использования подпрограмм в качестве процедурной
переменной:
- они должны компилироваться с ключом компилятора {$F+} или иметь директиву far для
получения полного адреса подпрограмм;
- они не должны быть стандартными процедурами и функциями;
- они не должны объявляться внутри других процедур и функций;
- они не должны быть типа inline или interrupt (пп. 10.5.5 и 10.5.6).
Пример.
($F+)
procedure Swap(var А, В: Byte);
var
Temp: Byte;
begin
Temp := A; A :=B; В := Temp
end;
function Tan(Angle: Real): Real;
begin
Tan:=Sin(Angle)/Cos(Angle)
{проверка, что Cos(Angle)<>0 осуществляется в основной
программе}
end;
{$F-}
В этом случае процедурным переменным, введенным ранее, можно присвоить значения:
Р2 := Swap;
F1 := Tan;
а вызовы P2(I,J) и F1(X) эквивалентны соответственно Swap(I,J) и Таn(Х).
Так же как и указатель, процедурная переменная занимает 4 байта памяти, в которых
помещается полный адрес подпрограммы (поэтому подпрограммы необходимо компилировать
с ключом {$F+}).
Процедурные переменные можно использовать так же, как и переменные
других типов: в выражениях (если эта переменная - функция), в виде оператора (если эта
переменная - процедура), как компонента другой более сложной переменной, как передаваемый
в подпрограмму параметр. Идея единства данных и подпрограмм получила дальнейшее развитие
в объектно-ориентированном программировании - см. п. 14.