Структурные
типы данных
Структурные типы данных
— это такие типы, которые состоят из данных других типов, в том числе из
данных структурного типа. К числу таких данных относятся:
Рассмотрим эти типы данных.
Строки
В Object Pascal имеются
строковые типы данных, которые перечислены в табл. 2.4.
Таблица
2.4. Строковые типы данных
Тип данных |
Максимальная
длина |
Занимаемая память |
Используется
для: |
|
255 символов |
2—256 байт |
совместимости с
предыдущими версиями языка |
|
2^31 символов |
4 байт— 2 Гбайт |
символов ANSI,
строк переменной длины |
|
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. Операции, допустимые над множествами
Обозначение |
Название |
Тип результата |
Результат |
Пример |
+ |
Объединение множеств |
Множество |
Неповторяющиеся
элементы первого и второго множества |
|
- |
Разность множеств |
Множество |
Элементы из первого
множества, которые отсутствуют во втором |
|
* |
Пересечение множеств |
Множество |
Элементы, которые
есть как в первом, так и во втором множестве |
|
Таблица
2.5 (окончание)
Обозначение |
Название |
Тип результата |
Результат |
Пример |
= |
Эквивалентность |
Логический |
Истина, если множества
эквивалентны, иначе — ложь |
|
о |
Неравенство |
Логический |
Истина, если множества
не являются эквивалентными, иначе — ложь |
|
<= |
Подмножество |
Логический |
Истина, если первое
множество входит во второе, |
|
>= |
Расширенный набор |
Логический |
ложь — в противном
случае Истина, если первое
множество включает в себя второе, иначе — ложь |
|
|
Членство |
Логический |
Истина, если данный
элемент входит в множество, иначе — ложь |
|
Массивы
Массив — это упорядоченная
совокупность элементов одного и того же типа. Элементы массива имеют уникальные
индексы. Массив обязательно имеет имя.
Так как элементы массива
имеют индексы, массивы могут содержать одинаковые значения неоднократно. Каждый
элемент массива однозначно определяется именем массива и собственным индексом.
Массивы подразделяются
на статические и динамические.
Статический массив
— это массив, размеры которого задаются при объявлении, т. е. это массив с четкими
границами индексов.
Статический массив определяется
следующей конструкцией языка Object Pascal:
array[indexTypel
, . . . , indexTypen] of baseType;
Каждый indexType
внутри квадратных скобок является порядковым типом, диапазон которого
не превышает 2 Гбайт. Диапазон каждого indexType
ограничивает число
элементов, входящих в массив.
Примечание
Хотя, по определению, индексом массива может быть любой порядковый тип, на практике обычно применяется тип
Integer
.
Для обращения к любому элементу
массива нужно указать сначала имя этого массива, а затем — в квадратных скобках
номер (индекс) элемента:
МуАггау[10];
Динамический массив
— это массив, в котором при объявлении указывается только тип его элементов.
Размеры динамических массивов изменяются в ходе выполнения программы.
Динамический массив задается
с помощью нижеприведенной конструкции:
array of baseType;
Язык Object Pascal поддерживает
многомерные массивы. Самым простым является одномерный массив. Его можно представить
как пронумерованную строку переменных (рис. 2.1). Приведем пример создания простого
одномерного массива.
Рис.
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.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
начинается вариантная часть. В этой части:
(tag)
является необязательной частью и представляет собой любую объявленную переменную
типа ordinalType
. Если вы не используете переменной, то можно
ставить двоеточие сразу после слова case;
ordinalType
— это порядковый тип; tag,
представленный в списке constantList,
должен быть единственным, без повторов;
(variant1 .. variantn)
должно содержать обычное описание поля, например
Fieidvar1: type1;
. Приведем пример использования
вариантной записи. Предположим, что запись должна содержать данные о человеке.
Назовем запись Person.
Пусть она содержит имя (поле FirstName
),
фамилию (поле LastName
), дату рождения (поле BirthDate
)
человека. Кроме того, если человек является гражданином России, в записи указывается
место его рождения (поле BirthPlace
). Если же человек — иностранец,
то в записи о нем должны присутствовать следующие поля: страна (поле Country
),
дата въезда в Россию (поле EntryDate
) и дата отъезда из России
(поле ExitDate
). Такую запись мы объявляем в листинге 2.1.
Листинг 2.1. Использование
вариантной записи
var Person = recordR><FirstName, LastName: string[40];
EntryDate, ExitDate: TDate);
BirthDate: TDate; case Citizen: Boolean of
True: (Birthplace: string [40]); False: (Country: string [20];
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.