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

Глава 5. Переменные и типизированные константы

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

Описания переменных

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

Описание переменной представляет собой список идентификато-

ров, которые обозначают новые переменные и их типы.

описание ┌────────────┐ ┌───┐ ┌───┐ ┌───┐

переменной ─>│список иден-├─>│ : ├─>│тип├─┬───────────┬─>│ ; ├>

│тификаторов │ └───┘ └───┘ │ │ └───┘

└────────────┘ │ ┌────────┐│

└>│absolute├┘

└────────┘

Тип, задаваемый для переменных, может быть идентификатором

типа, который был ранее описан в разделе описания типов того же

самого блока, или блока, в который входит данный блок, или моду-

ля, или же этот тип может быть новым определением типа.

При указании идентификатора в списке идентификаторов описа-

ния переменной этот идентификатор имеет силу идентификатора пере-

менной в том блоке, где это описание было указано. К этой пере-

менной можно обращаться из любого места этого блока, если ее

идентификатор не переопределен в блоке, входящем в первый. Пере-

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

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

на значение первоначальной переменной.

Приведем пример раздела описания переменной:

var

X,Y,Z: real;

I,J,K: integer;

Digit: 0..9;

C: Color;

Done,Error: boolean;

Operator: (plus, minus, times);

Hue1,Hue2: set of Color;

Today: Date;

Results: MeasureList;

P1,P2: Person;

Matrix: array[1..10,1..10] of Real;

Переменные, описанные вне процедуры и функции, называются

глобальными переменными и располагаются в сегменте данных. Пере-

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

кальными переменными и располагаются в сегменте стека.

B.Pascal 7 & Objects/LR - 73 -

Сегмент данных

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

Максимальный размер сегмента данных равен 65520 байт. При

компоновке программы (что автоматически осуществляется в конце

компиляции программы) глобальные переменные всех модулей, исполь-

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

программы, размещаются в сегменте данных.

Если для глобальных переменных требуется более 65520 байт,

то следует распределить большие структуры в виде динамических пе-

ременных. Дальнейшее описание этой темы можно найти в разделе

"Указатели и динамические переменные" настоящей главы.

Сегмент стека

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

Размер сегмента стека устанавливается с помощью директивы

компилятора $M и лежит в пределах от 1024 до 65520 байт. По умол-

чанию размер стека равен 16384 байт.

При каждой активизации (вызове) процедуры или функции в стек

помещается множество локальных переменных. При завершении работы

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

момент выполнения программы общий размер локальных переменных в

активных процедурах и функциях не должен превышать размера сег-

мента стека.

Примечание: Если вы пишете приложение для Windows, то

Windows налагает на сегменты данных и стека специальные

требования, так что рабочий максимум стека и область сег-

мента данных могут быть меньше, чем упомянутые максимальные

области сегмента данных и стека.

Директива компилятора $S используется для проверок перепол-

нения стека в программе. В состоянии {$S+}, принятом по умолча-

нию, генерируется код, осуществляющий проверку переполнения стека

в начале каждой процедуры или функции. В состоянии {$S-} такие

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

ное завершение работы системы, поэтому не следует отменять про-

верки стека, если нет абсолютной уверенности в том, что перепол-

нения не произойдет.

B.Pascal 7 & Objects/LR - 74 -

Абсолютные переменные

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

Переменные можно описать так, что они будут располагаться по

определенному адресу в памяти, и в этом случае они называются аб-

солютными переменными. Описание таких переменных должно содержать

после типа оператор absolute:

описание ┌────────┐ ┌─────────┐ ┌───┐ ┌─────────┐

абсолютной ───>│absolute├─┬─>│целое без├─>│ : ├─>│целое без├─┬─>

переменной └────────┘ │ │ знака │ └───┘ │ знака │ │

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

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

└──────>│идентификатор├────────────┘

│ переменной │

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

Отметим, что список идентификаторов в описании переменной

при указании оператора absolute может содержать только один иден-

тификатор.

Первая часть оператора absolute содержит сегмент и смещение,

то есть адрес, по которому переменная должна быть размещена.

CrtMode : byte absolute $0040:$0049;

Первая константа обозначает базу сегмента, а вторая опреде-

ляет смещение внутри этого сегмента. Обе константы не должны вы-

ходить за пределы диапазона от $0000 до $FFFF (от 0 до 65535).

В программах защищенного режима DOS и в Windows первую форму

оператор absolute нужно использовать очень аккуратно, если вообще

стоит это делать. Во время выполнения прикладной программы

Windows или DOS защищенного режима она может не иметь полномочий

доступа к областям памяти вне вашей программы. Попытка доступа к

этим областям памяти может привести к сбою программы.

B.Pascal 7 & Objects/LR - 75 -

Вторая форма оператора absolute используется для описания

переменной, которая помещается "поверх" другой переменной, то

есть по тому же самому адресу, что и другая переменная.

var

Str: string[32];

StrLen: byte absolute Str;

Это описание указывает, что переменная StrLen должна разме-

щаться с того же адреса, что и переменная Str, а поскольку первый

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

StrLen будет содержать длину Str.

Эту вторую форму оператора absolute можно без опасения ис-

пользовать при программировании в Windows или в защищенном режиме

DOS. Память, к которой вы обращаетесь, находится в области прог-

раммы.

B.Pascal 7 & Objects/LR - 76 -

Ссылки на переменные

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

Ссылка на переменную может обозначать следующее:

- переменную;

- компонент в переменной структурного или строкового типа;

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

типa указатель.

Синтаксис ссылки на переменную имеет вид:

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

ссылка на ─┬──>│идентификатор├────────────────────────────┬──>

переменную │ │ переменной │ ^^ ┌────────────┐ │

│ └─────────────┘ │└──┤квалификатор│<─┘

│ ┌───────────────┐ │ └────────────┘

├──>│приведение типа├──────┤

│ │ переменной │ │

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

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

└──>│выражение├─>│квалификатор├──┘

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

Отметим, что синтаксис ссылки на переменную допускает ис-

пользование выражения, вычисляющего значение ссылочного типа. Вы-

ражение должно следовать за квалификатором, разыменовывающим ссы-

лочное значение (или индексирующим значением указателя, если с

помощью директивы {$X+} разрешен расширенный синтаксис), что дает

фактическую ссылку на переменную.

B.Pascal 7 & Objects/LR - 77 -

Квалификаторы

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

Обращение к функции представляет собой идентификатор пере-

менной с несколькими квалификаторами или без них, которые изменя-

ют значение обращения к функции.

┌──────┐

квалификатор ──┬──>│индекс├──────────>

│ └──────┘ ^

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

├──>│ десигнатор ├──┤

│ │ поля │ │

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

│ ┌───┐ │

└──>│ ^ ├───────────┘

└───┘

Идентификатор массива без квалификатора является ссылкой на

весь массив, например:

Results

Идентификатор массива с указанным индексом обозначает конк-

ретный элемент массива, в данном случае структурную переменную:

Results[Current+1]

В случае, если элементом является запись, за индексом можно

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

начает конкретное поле конкретного элемента массива:

Results[Current+1].Data

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

волом указателя (^) с тем, чтобы указать различие между указате-

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

Results[Current+1].Data^

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

то можно добавить индексы для обозначения компонентов этого мас-

сива.

Results[Current+1].Data^[J]

B.Pascal 7 & Objects/LR - 78 -

Массивы, строки и индексы

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

Конкретный элемент массива обозначается с помощью ссылки на

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

данный элемент.

Конкретный символ в строковой переменной обозначается с по-

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

декс, определяющий позицию символа.

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

индекс ──>│ [ ├───────>│выражение├────┬──>│ ] ├──>

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

│ ┌───┐ │

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

└───┘

Индексные выражения обозначают компоненты в соответствующей

размерности массива. Число выражений не должно превышать числа

индексных типов в описании массива. Более того, тип каждого выра-

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

индексным типом.

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

индексов или несколько выражений в индексе. Например:

Matrix[I][J]

что тождественно записи:

Matrix[I,J]

Строковую переменную можно проиндексировать с помощью оди-

ночного индексного выражения, значение которого должно быть в ди-

апазоне 0...n, где n - указанный в описании размер строки. Это

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

символа имеет тип Char.

Первый символ строковой переменной (индекс 0) содержит дина-

мическую длину строки, то есть Length(S) тождественно Ord(S[0]).

Если атрибуту длины присваивается значение, то компилятор не про-

веряет, является ли это значение меньшим описанного размера стро-

ки. Вы можете указать индекс строки и вне ее текущей динамической

длины. В этом случае считываемые символы будут случайными, а

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

чение строковой переменной.

Когда с помощью директивы компилятора {$X+} разрешен расши-

ренный синтаксис, значение PChar может индексироваться одиночным

индексным выражением типа Word. Индексное выражение задает смеще-

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

для получения ссылки на переменную типа Char.

B.Pascal 7 & Objects/LR - 79 -

Записи и десигнаторы полей

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

Конкретное поле переменной-записи обозначается с помощью

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

ние поля, специфицирующее это поле.

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

обозначение поля ───>│ . │───>│идентификатор│───>

└───┘ │ поля │

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

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

Today.Year

Results[1].Count

Result[1].When.Month

В операторе, входящем в оператор with, обозначению поля не

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

Десигнаторы компонентов объекта

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

Формат десигнатора компонента объекта совпадает с форматом

десигнатора поля записи. То есть, он состоит из экземпляра (ссыл-

ки на переменную), за которым следует точка и идентификатор ком-

понента. Десигнатор компонента, который обозначает метод, называ-

ется десигнатором метода. К экземпляру объектного типа можно

применить оператор with. В этом случае при ссылке на компоненты

объектного типа экземпляр и точку можно опустить.

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

При этом эффект будет тот же, что и при записи перед ссылкой на

компонент Self и точки.

Переменные-указатели и динамические переменные

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

Значением переменной-указателя является или nil (то есть

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

переменную.

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

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

после которой ставится символ указателя (^).

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

помощью стандартных процедур New и GetMem. Вы можете использовать

B.Pascal 7 & Objects/LR - 80 -

операцию @ и стандартную функцию Ptr для создания значений указа-

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

ных.

Значение nil не указывает ни на какую переменную. Если вы

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

деленном значении указателя или указателе, равном nil, результат

будет неопределенным.

Приведем несколько примеров ссылок (указателей) на динами-

ческие переменные:

P1^

P1.Sibling^

Results[1].Data^

B.Pascal 7 & Objects/LR - 81 -

Приведение типов переменных

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

Ссылка на переменную одного типа может быть преобразована в

ссылку на переменную другого типа с помощью приведения типов пе-

ременных.

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

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

типов │ типа │ └───┘ │переменную│ └───┘

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

Когда приведение типов применяется к ссылке на переменную,

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

тавленного идентификатором типа. Размер переменной (число байт,

занимаемых переменной) должен быть равен размеру типа, представ-

ленного идентификатором типа. После приведения типа переменной

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

кается указанным типом.

Примечание: Определять допустимость приведения типа

должен программист.

Приведем несколько примеров приведения типов переменных:

type

TByteRec = record

lo, hi: byte;

end;

TWordRec = record

low, high: word;

end;

TPtrRec = record

ofs, seg: word;

end;

PByte = ^Byte;

var

B: byte;

W: word;

L: longint;

P: pointer;

begin

W := $1234;

B := TByteRec(W).lo;

TByteRec(W).hi := 0;

L := $1234567;

W := TWordRec(L).lo;

B := PByte(L)^;

P := Ptr($40,$49);

W := TPtrRec(P).seg;

Inc(TPtrRec(P).Ofs,4);

end.

B.Pascal 7 & Objects/LR - 82 -

Обратите внимание на использование для доступа к младшим и

старшим байтам слова типа TByteRec: это соответствует встроенным

функциям Lo и Hi, только над левой частью в операции присваивание

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

к младшим и старшим словам длинного целого, а также к смещению и

адресу сегмента указателя используются типы TWordRec и TPtrRec.

Borland Pascal также полностью поддерживает приведение типов

для процедурных типов. Например, имея следующие описания:

type

Func = function(X: Integer): Integer;

var

F: Func;

P: Pointer;

N: Integer;

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

F := Func(P); { присвоить F значение процедурного типа в P }

Func(P) := F; { присвоить P значение процедурного типа в F }

@F := P; { присвоить F значение-указатель в P }

P := @F; { присвоить P значение-указатель в F }

N := F(N); { вызвать функцию через F }

N := Func(P)(N); { вызвать функцию через P }

Обратите в частности внимание на операцию получения адреса

@, которая применяется к переменной процедурного типа. Ее можно

использовать в левой части присваивания. Кроме того, отметьте

приведение типа на последней строке при вызове функцию через пе-

ременную-указатель.

B.Pascal 7 & Objects/LR - 83 -

Типизированные константы

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

Типизированные константы можно сравнить с инициализированны-

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

входе в их блок. В отличие от нетипизированных констант в описа-

нии типизированной константы указывается как тип, так и значение

константы.

описание типизированной константы

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

└─>│идентификатор├─>│ : ├─>│тип├─>│ = ├─>│типизированная├──>

└─────────────┘ └───┘ └───┘ └───┘ │ константа │

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

типизированная ┌───────────────────┐

константа ──────┬───>│ константа ├───────>

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

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

├───>│ адресная константа├───┤

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

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

├───>│ константа-массив ├───┤

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

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

├───>│ константа-запись ├────┤

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

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

├───>│ константа-объект ├───┤

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

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

└───>│константа-множество├───┘

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

Типизированные константы можно использовать точно так же,

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

части оператора присваивания. Отметим, что типизированные конс-

танты инициализируются только один раз - в начале выполнения

программы. Таким образом, при каждом новом входе в процедуру или

функцию локально описанные типизированные константы заново не

инициализируются.

Кроме обычных выражений-констант значение типизированной

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

ты. Адресное выражение-константа - это выражение, предусматриваю-

щее получение адреса, смещения или сегмента глобальной перемен-

ной, типизированной константы, процедуры или функции. Адресные

выражения-константы не могут ссылаться на локальные переменные

(расположенные в стеке) или динамические переменные (размещенные

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

нельзя вычислить на этапе компиляции.

B.Pascal 7 & Objects/LR - 84 -

Константы простого типа

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

Описание типизированной константы с простым типом означает

указание значения константы:

const

Maximum : integer = 9999;

Factor : real = -0.1;

Breakchar : char = #3;

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

можно задать с помощью адресного выражение-константы, то есть вы-

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

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

ции. Например:

var

Buffer: array[0..1023] of Byte;

const

BufferOfs: Word = Ofs(Buffer);

BufferSeg: Word = Seg(Buffer);

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

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

заменяемой для обычных констант. Например, она не может использо-

ваться в описании других констант или типов.

const

Min : integer = 0;

Max : integer = 99;

type

Vector = array[Min..Max] of integer;

Описание Vector является недопустимым, поскольку Min и Max

являются типизированными константами.

Константы строкового типа

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

Описание типизированной константы строкового типа содержит

максимальную длину строки и ее начальное значение:

const

Heading : string[7] = 'Section';

NewLine : string[2] = #13#10;

TrueStr : string[5] = 'Yes';

FalseStr : string[5] = 'No';

B.Pascal 7 & Objects/LR - 85 -

Константы структурного типа

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

Описание константы структурного типа определяет значение

каждого компонента структуры. Borland Pascal поддерживает описа-

ния констант типа массив, запись, множество и указатель. Констан-

ты файлового типа и константы типа массив или запись, содержащие

компоненты файлового типа, не допускаются.

B.Pascal 7 & Objects/LR - 86 -

Константы типа массив

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

Описание константы типа массив содержит значения элементов,

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

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

константа-массив ───>│ ( ├────>│типизированная├──┬─>│ ) ├──>

└───┘ ^ │ константа │ │ └───┘

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

│ ┌───┐ │

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

└───┘

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

type

Status = (Active,Passive,Waiting);

StatusMap = array[Status] of string[7];

const

StatStr: StatusMap = ('Active','Passive','Waiting');

В этом примере определяется константа-массив StarStr, кото-

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

в соответствующие им строковые представления. Элементами массива

StarStr являются:

StatStr[Active] = 'Active'

StatStr[Passive] = 'Passive'

StatStr[Waiting] = 'Waiting'

Тип элемента константы-массива может быть любым, кроме фай-

лового типа. Упакованные константы строкового типа (символьные

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

строки. Определение:

const

Digits:array[0..9] of

char=('0','1','2','3','4','5','6','7','8','9');

можно представить в более удобном виде:

const

Digits: array[0..9] of char = '0123456789';

При разрешении расширенного синтаксиса (с помощью директивы

компилятора {$X+}) массивы с нулевой базой могут инициализирова-

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

мер:

const

FileName = array[0..79] of Char = 'TEXT.PAS';

B.Pascal 7 & Objects/LR - 87 -

В таких случаях оставшиеся символы устанавливаются в NULL

(#0), и массив содержит строку с завершающим нулем.

Примечание: Подробнее о строках с завершающим нулем

рассказывается в Главе 18.

При описании константы типа "многомерный массив" константы

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

запятыми. Расположенные в середине константы соответствуют самым

правым размерностям. Описание:

type

Cube = array[0..1,0..1,0..1] of integer;

const

Maze: Cube = (((0,1),(2,3)),((4,5),(6,7)));

задает следующие начальные значения массива Maze:

Maze[0, 0, 0] = 0

Maze[0, 0, 1] = 1

Maze[0, 1, 0] = 2

Maze[0, 1, 1] = 3

Maze[1, 0, 0] = 4

Maze[1, 0, 1] = 5

Maze[1, 1, 0] = 6

Maze[1, 1, 1] = 7

B.Pascal 7 & Objects/LR - 88 -

Константы типа запись

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

Описание константы типа запись содержит идентификатор и зна-

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

запятой.

константа-запись

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

└─>│ ( ├───>│идентификатор├─>│ : ├─>│типизированная├─┬─>│ ) ├─>

└───┘ ^ │ поля │ └───┘ │ константа │ │ └───┘

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

│ ┌───┐ │

└───────────────────┤ ; │<──────────────────┘

└───┘

Приведем несколько примеров констант-записей:

type

Point = record

x,y: real;

end;

Vector = array[0..1] of Point;

Month =

(Jan,Feb,Mar,Apr,May,Jun,Jly,Aug,Sep,Oct,Nov,Dec);

Date = record

d: 1..31; m: Month; y: 1900..1999;

end;

const

Origin : Point = (x: 0.0; y: 0.0);

Line : Vector = ((x: -3.1; y: 1.5),(x: 5.8; y: 3.0));

SomeDay : Date = (d: 2; m: Dec; y: 1960);

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

описании типа запись. Если запись содержит поля файлового типа,

то для этого типа запись нельзя описать константу. Если запись

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

анта. Если вариант содержит поле признака, то его значение должно

быть определено.

B.Pascal 7 & Objects/LR - 89 -

Константы объектного типа

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

При описании константы объектного типа используется тот же

синтаксис, что и при описании константы типа запись. Значения для

элементов (компонентов) метода задаваться не могут. С учетом при-

водимых ранее описаний объектных типов, приведем некоторые приме-

ры констант объектного типа:

const

ZeroPoint: Point = (X: 0; Y: 0)

ScreenRect: Rect = (A: (X: 0; Y: 0); B: (X: 80; Y: 25);

CountField: NumField = (X: 5; Y: 20; Len: 4; Name: nil;

Value: 0; Min: -999; Max: 999);

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

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

ра. Эта инициализация автоматически выполняется компилятором.

B.Pascal 7 & Objects/LR - 90 -

Константы множественного типа

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

Описание константы множественного типа может содержать нес-

колько элементов, заключенных в квадратные скобки и разделенных

запятыми. Каждый элемент такой константы представляет собой конс-

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

двумя точками.

┌───┐ ┌───┐

константа-множество ─>│ [ ├─┬────────────────────────────>│ ] ├>

└───┘ │ ┌─────────────────┐ ^ └───┘

└───>│константа-элемент├─┬─┘

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

│ ┌───┐ │

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

└───┘

┌─────────┐

константа-элемент ────>│константа├──┬─────────────────────────>

└─────────┘ │ ┌──┐ ┌─────────┐ ^

└─>│..├──>│константа├──┘

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

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

type

Digits = set of 0..9;

Letters = set of 'A'..'Z';

const

EvenDigits: Digits = [0,2,4,6,8];

Vowels : Letters = ['A','E','I','O','U','Y'];

HexDigits : set of '0'..'z' =

['0'..'9','A'..'F','a'..'f'];

B.Pascal 7 & Objects/LR - 91 -

Константы ссылочного типа

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

Описание константы ссылочного типа может содержать только

значение nil (пусто). Приведем несколько примеров:

type

TDirection = (Left, Right, Up, Down);

TStringPtr = ^String;

TNodePtr = ^Node;

TNode = record

Next: NodePtr;

Symbol: StringPtr;

Value: Direction;

end;

const

S1: string[4] = 'DOWN';

S2: string[2] = 'UP';

S3: string[5] = 'RIGHT';

S4: string[4] = 'LEFT';

N1: Node = (Next: nil; Symbol: @S1; Value: Down);

N2: Node = (Next: @N1; Symbol: @S2; Value: Up);

N3: Node = (Next: @N2; Symbol: @S3; Value: Right);

N2: Node = (Next: @N3; Symbol: @S4; Value: Left);

DirectionTable: NodePtr = @N4;

Если разрешен расширенный синтаксис (указана директива ком-

пилятора {$X+}), типизированная константа типа PChar может иници-

ализироваться строковой константой, например:

const

Message: PChar = 'Программа завершена';

Prompt: PChar = 'Введите значения: ';

Digits: array[0..9] of PChar = (

'Ноль', 'Один', 'Два', 'Три', 'Четыре',

'Пять', 'Шесть', 'Семь', 'Восемь', 'Девять');

Результатом будет то, что указатель теперь указывает на об-

ласть памяти, содержащую копию строкового литерала с завершающим

нулем. Подробности вы можете найти в Главе 18 "Строки с завершаю-

щим нулем".

B.Pascal 7 & Objects/LR - 92 -

Константы процедурного типа

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

Константы процедурного типа должны определять идентификатор

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

танты.

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

процедурная константа ──────┬───>│константа-элемент├───────────>

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

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

├───>│константа-элемент├───┤

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

│ ┌───┐ │

└─────────>│nil├───────────┘

└───┘

Приведем следующий пример:

type

ErrorProc = procedure(ErrorCode: Integer);

procedure DefaultError(ErrorCode: Integer); far;

begin

WriteLn('Error ', ErrorCode, '.');

end;

const

ErrorHandler: ErrorProc = DefaultError;

B.Pascal 7 & Objects/LR - 93 -

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]