Структурные типы данных

Структурные типы данных — это такие типы, которые состоят из данных других типов, в том числе из данных структурного типа. К числу таких данных относятся:

Рассмотрим эти типы данных.

Строки

В Object Pascal имеются строковые типы данных, которые перечислены в табл. 2.4.

Таблица 2.4. Строковые типы данных

Тип данных

Максимальная длина

Занимаемая память

Используется для:

ShortString

255 символов

2—256 байт

совместимости с предыдущими версиями языка

AnsiString

2^31 символов

4 байт— 2 Гбайт

символов ANSI, строк переменной длины

WideString

2^30 символов

4 байт— 2 Гбайт

символов Unicode, COM-серверов и интерфейсов

Кроме того, наиболее часто применяется тип данных String. Свойства данного типа зависят от директивы компилятора {$H}: если она включена {$H+}, то данный тип эквивалентен типу AnsiString. Если же она выключена {$H-}, то тип String будет равносилен типу ShortString. По умолчанию данная директива выключена.

Строки, по своему определению, являются массивами символов. Поэтому для обращения к любому символу строки достаточно указать название строковой переменной и номер символа (как при обращении к элементу массива):

var
A: Char;
MyString: String;
begin
A:=MyString[10];
end;

Кроме перечисленных в табл. 2.4 строковых типов данных, имеется еще один тип PChar, который является строкой с нулевым окончанием, т. е. в конце строки стоит код 0. Длина строки типа PChar может быть любой, но, естественно, не более чем объем памяти компьютера.

Множества

Множество — это набор данных, относящихся к одному и тому же простому типу. Значения входящих в множество элементов ограничены только своим простым типом. Количество элементов множества не должно превышать 256. Описание множественного типа можно осуществить так:

set of Тип данных;

Рассмотрим способ задания множества целых чисел путем определения промежутка чисел:
type

TSomeInts = 1..250;
TIntSet = set of TSomeInts;

В данном примере мы создаем тип множества TIntSet, который содержит набор целых чисел от 1 до 250. Перед этим мы создали свой тип TSomeInts, который является частью типа integer. Мы можем создать это же множество другим способом:

type TIntSet = set of 1..250;

В общем случае, элементы множества задаются с помощью простого их перечисления в квадратных скобках через запятую. Например, если ранее была записана представленная выше строка определения типа TIntSet, можно задать множества Set1 и Set2:

var Set1, Set2: TIntSet ;
. . .

Set1 := [1, 3, 5, 7, 9]; Set2 := [2, 4, 6, 8, 10]

Кроме того, вы можете задавать множества непосредственно в объявлении переменных с помощью конструкции set of:

var MySet: set of ' a ' . . ' z ' ;
...
MySet := [ ' a ' , ' b ' , ' c ' ] ;

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

Таблица 2.5. Операции, допустимые над множествами

Обозначение

Название

Тип результата

Результат

Пример

+

Объединение множеств

Множество

Неповторяющиеся элементы первого и второго множества

Set1 + Set2

-

Разность множеств

Множество

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

Set1 - Set2

*

Пересечение множеств

Множество

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

Set1 * Set2

Таблица 2.5 (окончание)

Обозначение

Название

Тип результата

Результат

Пример

=

Эквивалентность

Логический

Истина, если множества эквивалентны, иначе — ложь

Set1 = Set2

о

Неравенство

Логический

Истина, если множества не являются эквивалентными, иначе — ложь

Set1 <> Set2

<=

Подмножество

Логический

Истина, если первое множество входит во второе,

Set1 <= Set2

>=

Расширенный набор

Логический

ложь — в противном случае

Истина, если первое множество включает в себя второе, иначе — ложь

Set1 >= Set2

In

Членство

Логический

Истина, если данный элемент входит в множество, иначе — ложь

A in Set1

Массивы

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

Так как элементы массива имеют индексы, массивы могут содержать одинаковые значения неоднократно. Каждый элемент массива однозначно определяется именем массива и собственным индексом.

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

Статический массив — это массив, размеры которого задаются при объявлении, т. е. это массив с четкими границами индексов.

Статический массив определяется следующей конструкцией языка Object Pascal:

array[indexTypel , . . . , indexTypen] of baseType;

Каждый indexType внутри квадратных скобок является порядковым типом, диапазон которого не превышает 2 Гбайт. Диапазон каждого indexType ограничивает число элементов, входящих в массив.

Примечание

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

Для обращения к любому элементу массива нужно указать сначала имя этого массива, а затем — в квадратных скобках номер (индекс) элемента:

МуАггау[10];

Динамический массив — это массив, в котором при объявлении указывается только тип его элементов. Размеры динамических массивов изменяются в ходе выполнения программы.

Динамический массив задается с помощью нижеприведенной конструкции:

array of baseType;

Язык Object Pascal поддерживает многомерные массивы. Самым простым является одномерный массив. Его можно представить как пронумерованную строку переменных (рис. 2.1). Приведем пример создания простого одномерного массива.

2-02-1.jpg

Рис. 2.1. Одномерный массив на десять переменных

Статический одномерный массив:

var MyArray: array[1..100] of Char;

Данная запись задает одномерный массив с именем MyArray, который будет содержать 100 символьных переменных. Данные переменные будут иметь индекс от 1 до 100. Так, например, для доступа к пятому элементу массива нужно использовать запись MyArray [5] .

Динамический одномерный массив:

var MyFlexibleArray: array of Real;

Данное объявление, в отличие от предыдущего, не занимает память под будущий массив. Для того чтобы это сделать, можно воспользоваться вызовом процедуры SetLength. Например, команда

SetLength(MyFlexibleArray, 20);

отводит в памяти массив на 20 вещественных чисел с индексами от 0 до 19.

Примечание

Индексами динамических массивов всегда являются целые числа. Стартовый индекс — всегда 0.

Доступ к элементам динамического массива аналогичен доступу к элементам статического массива.

Более сложным примером массива является двумерный массив. Его можно представлять как таблицу переменных, составленную из строк и столбцов (рис. 2.2).

2-02-2.jpg

Рис. 2.2. Двумерный массив А на двадцать элементов

Задание статического двумерного массива:

var MyMatrix: array[1..10, 1..50] of Real;

Многомерные массивы называют еще и массивами массивов. То есть можно записать задание того же двумерного массива как:

var MyMatrix: array[1..10] of array[1..50] of Real;

Обращение к элементу массива происходит по всем его индексам. Например, для нашего двумерного массива доступ к элементу может выглядеть так: MyMatrix[5,30], либо MyMatrix[5] [30].

Для задания многомерного динамического массива можно использовать конструкцию языка:

array of array of baseType;

Например, создать двумерный динамический массив можно следующим образом:

var MyArray: array of array of integer;

Для того чтобы установить длину многомерного динамического массива с помощью процедуры setLength, нужно выполнить ее для всех индексов массива. Например,

SetLength(MyArray, 10,20);

Записи

Записи являются аналогом структур в других языках программирования. Они объединяют фиксированное число разнородных элементов (элементов разных типов). Каждый элемент записи имеет свое уникальное в пределах записи имя и называется полем.

Записи делятся на:

Фиксированная запись — это запись, которая состоит из фиксированного числа полей. Для объявления фиксированной записи применяется следующая конструкция языка Object Pascal:

Record
FieldList1: Type1;
...
FieldListN: TypeN;
End;

где FieldList1 — имя первого поля, a FieldListN — имя последнего, N-го поля записи.

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

Record
FieldList1: Type1;
...
FieldListN: TypeN;
case tag: ordinalType of

constantList1: (variant1);
...
constantListn: (variantn);

end;

Первая часть объявления записи, до слова case, такая же, как и в фиксированной записи. После слова case начинается вариантная часть. В этой части:

Приведем пример использования вариантной записи. Предположим, что запись должна содержать данные о человеке. Назовем запись Person. Пусть она содержит имя (поле FirstName), фамилию (поле LastName), дату рождения (поле BirthDate) человека. Кроме того, если человек является гражданином России, в записи указывается место его рождения (поле BirthPlace). Если же человек — иностранец, то в записи о нем должны присутствовать следующие поля: страна (поле Country), дата въезда в Россию (поле EntryDate) и дата отъезда из России (поле ExitDate). Такую запись мы объявляем в листинге 2.1.

Листинг 2.1. Использование вариантной записи

var Person = recordR><     FirstName, LastName: string[40];
BirthDate: TDate; case Citizen: Boolean of
True: (Birthplace: string [40]); False: (Country: string [20];
EntryDate, ExitDate: TDate);
end;

Переменная Citizen в представленном выше листинге должна быть истинна, если человек является гражданином России, и ложна — в противном случае.

Файлы

Файл — это именованная порядковая последовательность элементов одного типа, которая находится на внешнем запоминающем устройстве (дискете, жестком диске и др.).

По определению, можно сказать, что файл похож на одномерный динамический массив. Отличие все же есть. Файл размещается не в оперативной памяти компьютера, а на диске и не требует предварительного задания своего размера.

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

Файловая переменная — это переменная, которая связывается с конкретным файлом на диске. Все операции с этой переменной приводят к изменению физически размещенного на диске файла.

Файлы бывают разного типа, в зависимости от входящих в него элементов. Так, различают текстовые, типизированные и нетипизированные файлы.

Текстовые файлы состоят из строк текста переменной длины. Такие файлы объявляются с помощью слова Text File. Приведем пример объявления файловой переменной текстового файла:

var f: TextFile;

Типизированные файлы состоят из данных определенного (указанного) типа. Такие файлы объявляются с помощью конструкции file of typeData. Например:

var f1: file of real;       
     f2: file of boolean

Нетипизированные файлы могут содержать элементы, тип которых не указан. Такие файлы объявляются просто словом file. Например:

var f: file;

Кроме доступа к файлу с помощью файловых переменных, многие компоненты Kylix предоставляют свои собственные методы работы с файлами, такие как LoadFromFile или SaveToFile. О них мы расскажем далее, когда будем описывать свойства и методы основных компонентов Kylix.

Hosted by uCoz