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

Процедурные типы в выражениях

В общем случае использование процедурной переменной в опера-

торе или выражении означает вызов процедуры или функции, храня-

щейся в этой переменной. Однако, имеется исключение. Когда компи-

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

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

тавлять собой процедурное значение. Рассмотрим в качестве примера

следующую программу:

type

IntFunc = function: Integer;

var

F: IntFunc;

N: Integer;

function ReadInt: Integer; far;

var

I: Integer;

begin

Read(I);

ReadInt := I;

end;

begin

F := ReadInt; { присваивание процедурного значения }

N := ReadInt; { присваивание результата функции }

end.

Первый оператор основной программы присваивает процедурное

значение (адрес процедуры) ReadInt процедурной переменной F, вто-

рой оператор вызывает ReadInt и присваивает N возвращаемое значе-

ние. Различие между получением процедурного значения или вызовом

функции осуществляется по типу переменной, которой присваивается

значение (F или N).

К сожалению, есть ситуации, когда компилятор не может опре-

делить из контекста желаемое действие. Например, в следующем опе-

раторе для компилятора не очевидно, что нужно сделать: сравнить

процедурное значение в F с процедурным значением ReadInt, чтобы

определить, что F указывает в данный момент на ReadInt, или выз-

вать F и ReadInt, а затем сравнить возвращаемые значения:

if F = ReadInt then

WriteLn('Equal');

Однако, стандартный синтаксис Паскаля определяет, что вхож-

дение в выражение идентификатора функции означает вызов этой

функции, поэтому в результате предыдущего оператора будет выпол-

нен вызов F и ReadInt, а затем будут сравниваться возвращаемые

значения. Чтобы сравнить процедурное значение в F с процедурным

значением в ReadInt, нужно использовать следующую конструкцию:

if @F = @ReadInt then

WriteLn('Equal');

При применении к процедурной переменной, идентификатору про-

цедуры или функции операции получения адреса @, эта операция пре-

дотвращает вызов компилятором процедуры и в то же время преобра-

зует аргумент в указатель. Таким образом, @F преобразует F в не-

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

ReadInt. Для определения того, что F ссылается на ReadInt можно

сравнить два значения-указателя.

Операция @ часто используется при присваивании процедурной

переменной нетипизированного значения-указателя. Например, опре-

деленная в Windows (в модуле WinProcs) функция GetProcAddress

возвращает адрес экспортируемой функции в DLL как нетипизирован-

ной значение-указатель. С помощью операции @ вызов GetProcAddress

можно присвоить процедурной переменной:

type

TStrComp = function(Str1, Str2: PChar): Integer;

var

StrComp: TStrComp:

.

.

.

begin

.

.

.

@StrComp := GetProcAddress(KernelHandle, 'Lstrcmpi');

.

.

.

end.

Чтобы получить адрес в памяти процедурной переменной, а не

адрес, в ней записанный, используйте двойную операцию @ (@@).

Например, @P означает преобразование P в нетипизированный указа-

тель-переменную, в @@P означает возвращение физического адреса

переменной P.

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