Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЕКСТЫ для лабработы 2 / вариант №26.rtf
Скачиваний:
20
Добавлен:
14.03.2016
Размер:
330.04 Кб
Скачать

Volume(Radius, Height)

В режиме расширенного синтаксиса ($X+) вызовы функций можно

использовать в качестве операторов, то есть результат вызова

функции может отбрасываться.

B.Pascal 7 & Objects/LR - 113 -

Описатели множества

─────────────────────────────────────────────────────────────────

Описатель множества определяет значения множественного типа

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

скобки ([]). Каждое выражение определяет значение множества.

┌───┐ ┌───┐

описатель ───>│ [ ├──┬────────────────────────>│ ] ├───>

множества └───┘ │ ┌────────────┐ ^ └───┘

└───>│ группа ├──┬─┘

^ │ элементов │ │

│ └────────────┘ │

│ ┌───┐ │

└────┤ , │<────────┘

└───┘

┌───────────┐

группа элементов ──>│ выражение ├──┬───────────────────────────>

└───────────┘ │ ^

│ ┌──┐ ┌───────────┐ │

└─>│..├──>│ выражение ├─┘

└──┘ └───────────┘

Обозначение [ ] означает пустое множество, тип которого сов-

местим по присваиванию с типом любого множества. Любая группа

элементов, описанная, как х..у, объявляет элементами множества

все значения в диапазоне х..у. Если х больше, чем у, то х..у не

описывает никаких элементов и [x..y] обозначает пустое множество.

В конкретном описателе множества все значения выражения в

группах элементов должны быть одного порядкового типа.

Приведем некоторые примеры описателей множеств:

[red, C, green]

[1,5,10..K mod 12, 13, 23]

['A'..'Z', 'a'..'z', Chr(Digit+48)]

B.Pascal 7 & Objects/LR - 114 -

Приведение типа значений

─────────────────────────────────────────────────────────────────

Тип выражения можно изменить на другой тип с помощью приве-

дения типа значений.

┌─────────────┐ ┌───┐ ┌─────────┐ ┌───┐

приведение ───>│идентификатор├──>│ ( ├──>│выражение├──>│ ) ├─>

типа значения │ типа │ └───┘ └─────────┘ └───┘

└─────────────┘

Тип выражения и задаваемый тип должны оба иметь перечислимый

тип или тип указателей. Для перечислимых типов результирующее

значение получается путем преобразования выражения (и возможной

проверки на нахождение в допустимых границах). Преобразование мо-

жет привести к усечению или увеличению размера исходного значения

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

ражения. В том случае, когда значение расширяется, его знак всег-

да сохраняется. Таким образом, значение является расширяемым по

знаку.

Синтаксис приведения типа значений почти совпадает с синтак-

сисом приведения типа переменных (см. раздел "Приведение типа пе-

ременных" в Главе 5). Однако при приведении типа значений опера-

ции производятся со значениями, а не с переменными и, таким

образом, могут не участвовать в ссылках на переменные. То есть за

приведением типа значения не обязательно следуют квалификаторы. В

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

части оператора присваивания.

Некоторые примеры приведения типа значений включают в себя:

Intereg('A')

Char(48)

Boolean(0)

Color(2)

IntPtr(@Buffer)

BytePtr(Ptr($40,$49))

B.Pascal 7 & Objects/LR - 115 -

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

─────────────────────────────────────────────────────────────────

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

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

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

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

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

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

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

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, нужно использовать следующую конструкцию:

B.Pascal 7 & Objects/LR - 116 -

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.

B.Pascal 7 & Objects/LR - 117 -

───────────────────────────────────────────────────────────────────────

Соседние файлы в папке ТЕКСТЫ для лабработы 2