При создании любой серьёзной программы не обойтись без дополнительных,
более сложных, чем числа и строки, типов данных. В Delphi программист может для
своих целей конструировать собственные типы данных. Чтобы ввести в программу
(описать) новый тип данных, применяется оператор с ключевым словом type:
type название_типа = описание_типа;
Перечислимый тип - это тип данных, диапазоном значений которого является просто
набор идентификаторов. Это может применяться в тех случаях, когда нужно описать
тип данных, значения которого нагляднее представить не числами, а словами.
Перечислимый тип записывается взятой в круглые скобки последовательностью
идентификаторов - значений этого типа, перечисляемых через запятую. При этом,
первые элементы типа считаются младшими по сравнению с идущими следом. Например,
тип, описывающий названия футбольных команд, можно сформировать так:
type FootballTeam = (Spartak, Dinamo, CSKA, Torpedo, Lokomotiv);
var MyTeam: FootballTeam;
begin
MyTeam:=Spartak;
end;
Вообще, под перечислимыми типами понимают все типы, для которых можно определить
последовательность значений и их старшинство. К ним относятся:
все целочисленные типы, для которых всегда можно указать число, следующее за
числом N;
символьные типы (Char): за символом 'a' всегда следует 'b', за '0' следует '1',
и так далее;
логические типы - тип Boolean также представляет собой перечислимый тип: type
Boolean = (false, true);
Структурные типы данных используются практически в любой программе. Это такие
типы, как
массивы
записи
множества
Массив - это структура данных, доступ к элементам которой осуществляется по
номеру (или индексу). Все элементы массива имеют одинаковый тип.
Описание массива имеет вид:
type имя_типа_массива = array [диапазон] of тип_элемента;
Диапазон определяет нижнюю и верхнюю границы массива и, следовательно,
количество элементов в нём. При обращении к массиву индекс должен лежать в
пределах этого диапазона. Массив из ста элементов целого типа описывается так:
type TMyArray = array [1 .. 100] of Integer;
Теперь можно описать переменные типа TMyArray:
var A, B: TMyArray;
Вместо присвоения типа можно явно описать переменные как массивы:
var A, B : array [1..100] of Integer;
Для доступа к элементу массива нужно указать имя массива и индекс элемента в
квадратных скобках. В качестве индекса может выступать число, идентификатор или
выражение, значение которых должно укладываться в диапазон, заданный при
описании массива:
var N: Integer;
begin
N := 65;
A[5] := 101;
A[N] := 165;
A[N+3] := 200;
B := A;
end;
Иногда требуется узнать верхнюю или нижнюю границу массива. Для этого служат
встроенные функции:
High() - вернёт число, являющееся верхней границей массива;
Low() - вернёт число, являющееся нижней границей массива.
В скобки нужно подставить массив, границы которого требуется узнать.
Выражение B := A означает, что каждый элемент массива B будет равен элементу с
таким же индексом массива A. Такое присвоение возможно только если оба массива
объявлены через некий поименованный тип, или перечислены в одном списке. И в
случае:
var A: array[1..100] of String;
B: array[1..100] of String;
его использовать невозможно (но возможно поэлементное присвоение B[1] := A[2]; и
т.д.).
Массивы могут иметь несколько измерений, перечисляемых через запятую. Например,
таблицу из четырёх столбцов и трёх строк: 1 2 3 4
5 6 7 8
9 10 11 12
можно описать в виде массива с двумя измерениями:
type MyTable = array[1..4, 1..3] of Integer;
var X : MyTable;
Y : Integer;
begin
Y:=X[3, 2];
end;
Теперь в результате операции присвоения Y будет равен 7.
Многомерный, например, двумерный массив можно описать как массив массивов:
type TMyArray = array [1 .. 4] of array [1 .. 3] of Integer;
Результат будет аналогичен предыдущему примеру.
Каждое измерение многомерного массива может иметь свой собственный тип, не
обязательно целый.
Кроме вышеописанных, так называемых статических массивов, у которых количество
элементов неизменно, в Delphi можно использовать динамические массивы,
количество элементов в которых допускается изменять в зависимости от требований
программы. Это позволяет экономить ресурсы компьютера, хотя работа с такими
массивами происходит гораздо медленнее. Описываются динамические массивы
аналогично статическим, но без указания диапазона индексов:
type TDinArray = array of Integer;
var A : TDinArray;
После создания в динамическом массиве нет ни одного элемента. Необходимый размер
задаётся в программе специальной процедурой SetLength. Массив из ста элементов:
begin
SetLength(A, 100);
end;
Нижняя граница динамического массива всегда равна нулю. Поэтому индекс массива A
может изменяться от 0 до 99.
Многомерные динамические массивы описываются именно как массивы массивов.
Например, двумерный:
type T3DinArray = array of array of Integer;
var A : T3DinArray;
В программе сначала задаётся размер по первому измерению (количество столбцов):
SetLength(A, 3);
Затем задаётся размер второго измерения для каждого из трёх столбцов, например:
SetLength(A[0], 3);
SetLength(A[1], 2);
SetLength(A[2], 1);
Таким образом создаётся треугольная матрица: A00 A10 A20
A01 A12
A02
Чтобы освободить память, выделенную динамическому массиву, нужно массиву как
целому присвоить значение nil:
A:=nil;
Ключевое слово nil в Delphi означает отсутствие значения.
Записи очень важный и удобный инструмент. Даже не применяя специальные
технологии, с его помощью можно создавать собственные базы данных. Записи - это
структура данных, каждый элемент которой имеет собственное имя и тип данных.
Элемент записи иначе называют поле. Описание записи имеет вид:
type имя_типа_записи = record
название_поля : тип_поля ;
. . .
название_поля : тип_поля ;
end;
Названия полей, имеющих одинаковый тип, можно, как и в случае описания
переменных, указывать в одну строку через запятую. Для обращения к полю записи
сначала указывают имя записи, затем точку, затем имя поля. Например, данные о
персонале предприятия могут быть организованы таким типом записи:
type TPers = record
Fam, Name, Par : String;
Year : Integer;
Dep : String;
end;
var Pers : TPers;
begin
Pers.Fam:='Иванов';
Pers.Name:='Иван';
Pers.Par:='Иванович';
Pers.Year:=1966;
Pers.Dep:='Цех №1';
end;
Теперь осталось записать эти данные в файл, предварительно объявив и его тип как
TPers, и база данных готова. С файлом в Delphi также ассоциируется переменная,
называемая файловой переменной, которая описывается так:
VFile : file of тип_файла;
В качестве типа может использоваться любой ограниченный тип Delphi. При этом не
допускается тип String, так как он допускает переменный размер до 2 ГБайт. Его
необходимо ограничивать: String[N], где N - количество символов. Тип TPers из
предыдущего примера должен быть описан, например, так:
type TPers = record
Fam, Name, Par : String[20];
Year : Integer;
Dep : String[10];
end;
Теперь переменная такого типа занимает строго определённое место в памяти, и
может быть записана в файл. Как это сделать, рассказывается во 2-й части Урока
№7.
Множество - это группа элементов, объединённая под одним именем, и с которой
можно сравнивать другие величины, чтобы определить, принадлежат ли они этому
множеству. Количество элементов в одном множестве не может превышать 256.
Множество описывается так:
type имя_множества = set of диапазон_значений_множества ;
В качестве диапазона может указываться любой тип, количество элементов в котором
не больше 256. Например:
type TMySet = set of 0 .. 255;
type TMySet = set of Byte;
Конкретные значения множества задаются в программе с помощью перечисления
элементов, заключённых в квадратные скобки. Допускается использовать и
диапазоны:
var MySet : TMySet;
begin
MySet:=[1, 3 .. 7, 9];
end;
Чтобы проверить, является ли некое значение элементом множества, применяется
оператор in в сочетании с условным оператором:
var Key : Char;
Str : String;
begin
if Key in ['0' .. '9', '+', '-'] then Str:='Math';
end;
Чтобы добавить элемент во множество, используется операция сложения, удалить -
вычитания:
var Digit: set of Char=['1'..'9'];
var Math: Set of Char;
begin
Math:=Digit+['+', '-', DecimalSeparator*];
end;
*Примечание: DecimalSeparator - встроенная в Delphi константа типа Char, имеющая
значение символа-разделителя целой и дробной частей, который может быть равен
точке ('.') либо запятой (','), в зависимости от текущих настроек Windows.