TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

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

             В общем случае использование процедурной переменной в опера-
        торе  или выражении означает вызов процедуры или функции,  храня-
        щейся в этой переменной. Однако, имеется исключение. Когда компи-
        лятор видит,  что процедурная переменная находится в левой  части
        оператора присваивания,  он знает, что правая часть должна предс-
        тавлять собой процедурное значение. Рассмотрим в качестве примера
        следующую программу:

             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.

Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz