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

B.Pascal 7 & Objects/LR - 42 -

Вещественные типы

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

К вещественному типу относится подмножество вещественных чи-

сел, которые могут быть представлены в формате с плавающей точкой

с фиксированным числом цифр. Запись значения в формате с плаваю-

щей запятой обычно включает три значения - m, b и e - таким обра-

зом, что m x b^e=n, где b всегда равен 2, а m и e являются цело-

численными значениями в диапазоне вещественного типа. Эти

значения m и e далее определяют диапазон представления и точность

вещественного типа.

Имеется пять видов вещественных типов: вещественное (Real),

с одинарной точностью (Single), с двойной точностью (Double), с

повышенной точностью (Extended) и сложное (Comp). Действия над

типами с одинарной точностью, с двойной точностью и с повышенной

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

чии числового сопроцессора 8087 (который был описан ранее).

Вещественные типы различаются диапазоном и точностью связан-

ных с ними значений (см. Таблицу 4.2).

Диапазон представления

и десятичные цифры для вещественных типов Таблица 4.2

┌───────────────────────┬───────────────────────────┬───────────┐

│ Тип │ Диапазон │ Цифры │

├───────────────────────┼───────────────────────────┼───────────┤

│ вещественное │2.9x10^-39 .. 1.7x10^38 │от 11 до 12│

│ (Real) │ │ │

├───────────────────────┼───────────────────────────┼───────────┤

│ с одинарной точностью │1.5x10^-45 .. 3.4x10^38 │от 7 до 8 │

│ (Single) │ │ │

├───────────────────────┼───────────────────────────┼───────────┤

│ с двойной точностью │5.0x10^-324 .. 1.7x10^308 │от 15 до 16│

│ (Double) │ │ │

├───────────────────────┼───────────────────────────┼───────────┤

│ с повышенной точностью│1.9x10^-4951 .. 1.1x10^4932│от 19 до 20│

│ (Extended) │ │ │

├───────────────────────┼───────────────────────────┼───────────┤

│ сложный тип │ -2^63 + 1 .. 2^63 - 1 │ │

│ (Comp) │ │ │

└───────────────────────┴───────────────────────────┴───────────┘

Примечание: Сложный тип содержит только целочисленные

значения в диапазоне от -2^63+1 до 2^63-1, что приблизи-

тельно равно -9.2x10^18 и 9.2x10^18.

Borland Pascal поддерживает две модели генерации кода для

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

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

Выбор соответствующей модели осуществляется с помощью директивы

компилятора $N.

B.Pascal 7 & Objects/LR - 43 -

Программная поддержка чисел с плавающей точкой

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

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

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

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

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

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

ное). Любая попытка оттранслировать операторы, выполняющие дейс-

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

вышенной точностью и над сложными типами, вызовет сообщение об

ошибке.

Аппаратная поддержка чисел с плавающей точкой

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

В состоянии {$N+} генерируемый код выполняет все вычисления

над вещественными типами с помощью числового сопроцессора 8087.

Это состояние позволяет использовать все пять вещественных типов,

однако оно требует наличия сопроцессора 8087 на этапе компиляции

и выполнения.

Borland Pascal включает в себя библиотеки исполняющей систе-

мы, которые автоматически эмулируют программным путем сопроцессор

80х87, если при выполнении прикладной программы DOS реального или

защищенного режима он отсутствует. Для определения того, следует

ли в программу DOS включить эмулятор сопроцессора 80x87, исполь-

зуется директива компилятора $E. Если вы создает прикладную прог-

рамму для реального или защищенного режима DOS, и сопроцессор

80х87 отсутствует, разрешение директивы компилятора $E обеспечи-

вает полную программную эмуляцию сопроцессора 80x87. Для программ

Windows директива $E не действует, так как Windows обеспечивает

собственные подпрограммы эмуляции.

Примечание: Более детальное описание генерации кода

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

те найти в Главе 15 "Использование сопроцессора 8087 в

Borland Pascal".

B.Pascal 7 & Objects/LR - 44 -

Строковые типы

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

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

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

ного числа символов при выполнении программы) и постоянным атри-

бутом размера в диапазоне от 1 до 255. Текущее значение атрибута

длины можно получить с помощью стандартной функции Length.

┌──────┐

строковый тип ───>│string├──┬──────────────────────────────>

└──────┘ │ ^

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

└─>│ [ ├──>│целое├──>│ ] ├─┘

└───┘ │ без │ └───┘

│знака│

└─────┘

Примечание: Операторы работы со строковыми типами опи-

сываются разделах "Строковые операторы" и "Операторы отно-

шений" Главы 6.

Отношение между любыми двумя строковыми значениями устанав-

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

соответствующих позициях. В двух строках разной длины каждый сим-

вол более длинной строки без соответствующего символа в более ко-

роткой строке принимает значение "больше"; например, 'Xs' больше,

чем 'X'. Нулевые строки могут быть равны только другим нулевым

строкам, и они являются наименьшими строковыми значениями.

Примечание: Стандартные процедуры и функции для работы

со строковыми типами описаны в разделе "Строковые процедуры

и функции".

К символам в строках можно обращаться как к элементам масси-

ва. См. раздел "Массивы, строки и индексы" в Главе 5.

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

строкового типа можно применять стандартные функции Low и High. В

этом случае функция Low возвращает 0, а High возвращает атрибут

размера (максимальную длину) данной строки.

Параметр-переменная, описанная с помощью идентификатора

OpenString и ключевого слова string в состоянии {$P+}, является

открытым строковым параметром. Открытые строковые параметры поз-

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

переменные изменяющегося размера.

Примечание: Открытые строковые параметры описываются в

Главе 9.

B.Pascal 7 & Objects/LR - 45 -

Структурные типы

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

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

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

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

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

Структурный тип может иметь неограниченные уровни структурирова-

ния.

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

структурный ──┬────────────────┬──>│ тип массив ├─────>

тип │ ┌────────┐ ^ │ └───────────────┘ ^

└─>│ packed ├─┘ │ ┌───────────────┐ │

└────────┘ ├──>│ множественный ├──┤

│ │ тип │ │

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

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

├──>│ файловый тип ├──┤

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

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

├──>│ тип "запись" ├──┤

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

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

└──>│ объектный тип ├──┘

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

Слово packed (упакованный) в описании структурного типа тре-

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

уменьшения скорости доступа к компоненту в переменной этого типа.

Слово packed не имеет никакого действия в Borland Pascal, пос-

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

возможно.

B.Pascal 7 & Objects/LR - 46 -

Типы массив

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

Массивы содержат фиксированное число элементов одного типа,

так называемого типа элемента. На приводимой ниже синтаксической

диаграмме тип элемента следует за словом of.

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

тип ──>│ array ├─>│ [ ├───>│ тип ├─┬─>│ ] ├─>│ of ├─>│ тип ├>

массив └───────┘ └───┘ ^ │индекса│ │ └───┘ └────┘ └─────┘

│ └───────┘ │

│ ┌───┐ │

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

└───┘

тип ┌────────────────┐

индекса ───>│ порядковый тип ├───>

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

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

указывается число элементов. Допустимыми индексными типами явля-

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

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

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

типа; число элементов поэтому равно числу значений в каждом ин-

дексном типе. Число размерностей не ограничено.

Приведем пример типа массив:

array[1..100] of Real

Если тип элемента в типе массив также является массивом, то

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

многомерный массив. Например,

array[boolean] of array[1..100] of array[Size] of Real

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

array[boolean,1..10,Size] of Real

Кроме того, можно записать выражение:

packed array[1..10] of packed array[1..8] of Boolean

как

packed array[1..10,1..8] of Boolean

Для доступа к элементам массива необходимо указать идентифи-

катор массива с одним или несколькими индексами в скобках (см.

раздел "Массивы, строки и индексы").

Тип массив, имеющий вид:

B.Pascal 7 & Objects/LR - 47 -

packed array[M..N] of Char

где M меньше N, называется упакованным строковым типом (слово

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

Borland Pascal). Упакованный строковый тип имеет некоторые свойс-

тва, не характерные для других типов массив (см. раздел "Тождест-

венные и совместимые типы" далее в этой главе).

Массив вида:

array[0..X] of Char

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

базой. Массивы с нулевой базой используются для хранения строк с

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

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

базой совместим со значением типа PChar. Полностью эта тема об-

суждается в Главе 18 "Использование строк с завершающим нулем".

Параметр, описанный с помощью синтаксиса array of T, называ-

ется открытым строковым параметром. Открытые строковые параметры

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

вые переменные изменяющегося размера.

Примечание: Открытые строковые параметры описываются в

Главе 9.

B.Pascal 7 & Objects/LR - 48 -

Типы запись

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

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

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

ет тип каждого поля и идентификатор, который именует поле.

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

тип запись ───>│ record ├──┬────────────────>│ end ├──>

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

└─>│ список ├─┘

│ полей │

└────────┘

список ┌────────────┐

полей┬─>│ фиксирован-├─┬────────────────────────────┬──────────>

│ │ ная часть │ │ ┌───┐ ┌────────────┐ ^ │ ┌───┐ ^

│ └────────────┘ └─>│ ; ├───>│ вариантная ├─┘ └─>│ ; ├─┘

│ └───┘ ^ │ часть │ └───┘

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

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

фиксированная ────>│ список ├──>│ : ├───>│ тип ├──┬──>

часть ^ │ идентификаторов │ └───┘ └─────┘ │

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

│ │

│ ┌───┐ │

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

└───┘

Фиксированная часть типа запись содержит список фиксирован-

ных полей вместе с идентификатором и типом для каждого поля. Каж-

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

тем же способом.

Приведем пример типа запись:

record

year: integer; { год }

month: 1..12; { месяц }

day: 1..31; { число }

end

B.Pascal 7 & Objects/LR - 49 -

В вариантной части, изображенной на синтаксической диаграмме

описания типа запись, память распределяется более чем для одного

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

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

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

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

вариантная часть

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

└─>│case├─┬───────────────────>│тип поля├─>│of├────>│вариант├─┬>

└────┘ │ ^ │признака│ └──┘ ^ └───────┘ │

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

└>│иденти-├>│ : ├─┘ └────┤ ; │<───┘

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

└───────┘

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

тип поля ────>│ идентификатор ├────>

признака │порядкового типа│

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

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

вариант ────>│константа├─┬─>│ : ├─>│ ( ├─┬─────────────>│ ) ├──>

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

│ ┌───┐ │ │ │

└────┤ , │<────┘ │ ┌──────┐ │

└───┘ └─>│список├─┘

│полей │

└──────┘

Вы можете видеть на диаграмме, что каждый вариант идентифи-

цирован по крайней мере одной константой. Все константы должны

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

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

один и тот же.

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

тор - идентификатор признака поля. При наличии идентификатора

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

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

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

ся активным в настоящий момент. Без указания поля признака

программа выбирает вариант по другому критерию.

Ниже приводятся несколько примеров типов запись:

record

firstName,lastName : string[40];

birthDate : Date;

case citizen : boolean of

True : (birthPlace: string[40]);

False : (country : string[20];

B.Pascal 7 & Objects/LR - 50 -

entryPort : string[20];

entryDate : Date;

exitDate : Date);

end

record

X,y : real;

case kind : Figure of

rectangle : (height,wigth: real); { прямоугольник }

triangle : (size1,side2,angle: real); { треугольник }

circle : (radius: real); { круг }

end

Объектные типы

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

Объектный тип является структурой, состоящей из фиксирован-

ного числа компонентов. Каждый компонент является либо полем, со-

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

ющим операции над объектом. По аналогии с описанием переменных,

описание поля указывает тип данного этого поля и идентификатор,

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

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

тора или деструктора.

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

го типа. Если T2 наследует от T1, то T2 является потомком T1, а

T1 является родителем T2.

B.Pascal 7 & Objects/LR - 51 -

Наследование является транзитивным, то есть если T3 наследу-

ет от T2, а T2 наследует от T1, то T3 наследует от T1. Область

(домен) объектного типа состоит из него самого и из всех его нас-

ледников.

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

тип объекта──>│object├─┬───────────────────>│список компонент├─┐

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

└─>│Hаследование├─┘ │

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

┌───────────────────────────────────────────┘

│ ┌───┐

└─┬──────────────────────────────────┬─┤end├>

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

└──>│private├──>│список компонент├─┘

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

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

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

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

список компонент ──┬─────────────────┬───────────────────>

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

└─>│ список ├──┘ └─>│ список ├──┘

│ полей │ │ методов │

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

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

список полей ───>│cписок идентификаторов├─>│ : ├─>│type├>│ ; ├┬>

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

│ │

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

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

список методов ──>│заголовок├─┬──────────────────────────┤ ; ├┬─>

^ │ метода │ │ ┌───┐ ┌───────┐ ^└───┘│

│ └─────────┘ └>│ ; ├─>│virtual├┬───────┘ │

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

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

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

│ └>│ целая ├┘│

│ │константа│ │

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

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

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

заголовок метода ────┬───>│ заголовок процедуры ├──────>

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

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

├───>│ заголовок функции ├──┤

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

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

B.Pascal 7 & Objects/LR - 52 -

├───>│ заголовок конструктора ├──┤

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

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

└───>│ заголовок деструктора ├──┘

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

Следующий исходный код приводит пример описания объектного

типа. Далее во всей этой главе на данное описание будут делаться

ссылки.

type

Point = object

X, Y: integer;

end;

Rect = object

A, B: TPoint;

procedure Init(XA, YA, XB, YB: Integer);

procedure Copy(var R: TRectangle);

procedure Move(DX, DY: Integer);

procedure Grow(DX, DY: Integer);

procedure Intersect(var R: TRectangle);

procedure Union(var R: TRectangle);

function Contains(P: Point): Boolean;

end;

StringPtr = ^String;

FieldPtr = ^TField;

TField = object

X, Y, Len: Integer;

Name: StringPtr;

constructor Copy(var F: TField);

constructor Init(FX, FY, FLen: Integer; FName: String);

destructor Done; virtual;

procedure Display; virtual;

procedure Edit; virtual;

function GetStr: String; virtual;

function PutStr(S: String): Boolean; virtual;

end;

StrFieldPtr = ^TStrField;

StrField = object(TField)

Value: PString;

constructor Init(FX, FY, FLen: Integer; FName: String);

destructor Done; virtual;

function GetStr: String; virtual;

function PutStr(S: String): Boolean;

virtual;

function Get: string;

procedure Put(S: String);

end;

B.Pascal 7 & Objects/LR - 53 -

NumFieldPtr = ^TNumField;

TNumField = object(TField)

private

Value, Min, Max: Longint;

public

constructor Init(FX, FY, FLen: Integer; FName: String;

FMin, FMax: Longint);

function GetStr: String; virtual;

function PutStr(S: String): Boolean; virtual;

function Get: Longint;

function Put(N: Longint);

end;

ZipFieldPtr = ^TZipField;

ZipField = object(TNumField)

function GetStr: String; virtual;

function PutStr(S: String): Boolean;

virtual;

end;

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

только в разделе описаний типов, находящемся на самом внешнем

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

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

или внутри блока процедуры, функции или метода.

Тип компоненты файлового типа не может иметь объектный тип

или любой структурный тип, содержащий компоненты объектного типа.

B.Pascal 7 & Objects/LR - 54 -

Компоненты и область действия

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

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

пределы объектного типа. Более того, область действия идентифика-

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

конструкторов и деструкторов, которые реализуют методы объектного

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

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

го типа и внутри всех его наследников, а также внутри всех его

методов.

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

части private описания типа, ограничивается модулем (программой),

которая содержит описание объектного типа. Другими словами, част-

ные (private) компоненты-идентификаторы действуют, как обычные

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

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

идентификаторы неизвестны и недоступны. Поместив в один модуль

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

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

компоненты будут неизвестны другим модулям.

В описании объектного типа заголовок метода может задавать

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

полное. Это иллюстрируется методами Copy, Intersect и Union типа

TRectange в предыдущем примере.

Методы

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

Описание метода внутри объектного типа соответствует опере-

жающему описанию метода (forward). Таким образом, где-нибудь пос-

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

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

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

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

ется уточненный идентификатор метода. Он состоит из идентификато-

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

Как и любому другому идентификатору, идентификатору уточненного

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

и точка.

уточненный идентификатор метода

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

└─>│идентификатор объектного типа├>│ . ├>│идентификатор метода├>

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

Виртуальные методы

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

По умолчанию, методы являются статическими, однако они мо-

B.Pascal 7 & Objects/LR - 55 -

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

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

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

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

мя выполнения. Это иногда называют поздним связыванием.

Если объектный тип объявляет или наследует какой-либо вирту-

альный метод, то переменные этого типа должны быть инициализиро-

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

ального метода. Таким образом, объектный тип, который описывает

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

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

Объектный тип может переопределять любой из методов, которые

он наследует от своих родителей. Если описание метода в потомке

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

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

ле. Область действия переопределяющего метода расширяется до сфе-

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

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

лен снова.

Переопределение статического метода не зависит от изменения

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

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

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

лее того, переопределение опять же должно включать директиву

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