Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
BorlandPascal.doc
Скачиваний:
54
Добавлен:
17.03.2015
Размер:
2.83 Mб
Скачать

Процедурные переменные

После определения процедурного типа появляется возможность

описывать переменные этого типа. Такие переменные называют проце-

дурными переменными. Например, с учетом описаний типа из предыду-

щего примера, можно объявить следующие переменные:

var

P: SwapProc;

F: MathFunc;

Как и целая переменная, которой можно присвоить значение це-

лого типа, процедурной переменной можно присвоить значение проце-

дурного типа. Таким значением может быть, конечно, другая проце-

дурная переменная, но оно может также представлять собой иденти-

фикатор процедуры или функции. В таком контексте описания проце-

дуры или функции можно рассматривать, как описание особого рода

константы, значением которой является процедура или функция. Нап-

ример, пусть мы имеем следующие описания процедуры и функции:

procedure Swap(var A,B: integer);

var

Temp: integer;

begin

Temp := A;

A := B;

B := Temp;

end.

function Tan(Angle: real): real;

begin

Tan := Sin(Angle) / Cos(Angle);

end.

Описанным ранее переменным P и F теперь можно присвоить зна-

чения:

P := Swap;

F := Tan;

После такого присваивания обращение P(i,j) эквивалентно Swap

(i,j) и F(X) эквивалентно Tan(X).

Как и при любом другом присваивании, значения переменной в

левой и в правой части должны быть совместимы по присваиванию.

Процедурные типы, чтобы они были совместимы по присваиванию,

должны иметь одно и то же число параметров, а параметры на соот-

ветствующих позициях должны быть одинакового типа. Как упомина-

лось ранее, имена параметров в описании процедурного типа никако-

го действия не вызывают.

Кроме того, для обеспечения совместимости по присваиванию

процедура и функция, если ее нужно присвоить процедурной перемен-

ной, должна удовлетворять следующим требованиям:

- Это не должна быть стандартная процедура или функция.

- Такая процедура или функция не может быть вложенной.

- Такая процедура не должна быть процедурой типа inline.

- Она не должна быть процедурой прерывания (interrupt).

Стандартными процедурами и функциями считаются процедуры и

функции, описанные в модуле System, такие, как Writeln, Readln,

Chr, Ord. Чтобы получить возможность использовать стандартную

процедуру или функцию с процедурной переменной, вы должны напи-

сать для нее специальную "оболочку". Например, пусть мы имеем

процедурный тип:

type

IntProc = procedure(N: integer);

Следующая процедура для записи целого числа будет совмести-

мой по присваиванию:

procedure WriteInt(Number: Integer); far;

begin

Write(Number);

end.

Вложенные процедуры и функции с процедурными переменными ис-

пользовать нельзя. Процедура или функция считается вложенной,

когда она описывается внутри другой процедуры или функции. В сле-

дующем примере процедура Inner вложена в процедуру Outer и поэто-

му ее нельзя присваивать процедурной переменной:

program Nested;

procedure Outer;

procedure Inner;

begin

Writeln('Процедура Inner является вложенной');

end;

begin

Inner;

end;

begin

Outer;

end.

Использование процедурных типов не ограничивается просто

процедурными переменными. Как и любой другой тип, процедурный тип

может участвовать в описании структурного типа, что видно из сле-

дующих описаний:

type

GotoProc = procedure(X,Y: integer);

ProcList = array[1..10] of GotoProc;

WindowPtr = ^WindowRec;

Window = record

Next: WindowPtr;

Header: string[31];

Top,Left,Bottom,Right: integer;

SetCursor: GotoProc;

end;

var

P: ProcList;

W: WindowPtr;

С учетом этих описаний допустимы следующие вызовы процедур:

P[3](1,1);

W.SetCursor(10,10);

Когда процедурной переменной присваивается значение процеду-

ры, то на физическом уровне происходит следующее: адрес процедуры

сохраняется в переменной. Фактически, процедурная переменная

весьма напоминает переменную-указатель, только вместо ссылки на

данные она указывает на процедуру или функцию. Как и указатель,

процедурная переменная занимает 4 байта (два слова), в которых

содержится адрес памяти. В первом слове хранится смещение, во

втором - сегмент.

Соседние файлы в предмете Программирование на Pascal