Власні і структурні типи даних Delphi
При створенні будь-якої серйозної програми не обійтися без додаткових, більш складних, ніж числа і рядки, типів даних. У 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]; і т.д.).
Масиви можуть мати кілька вимірів, що перераховуються через кому. Наприклад, таблицю з чотирьох стовпців і трьох рядків:
|
можна описати у вигляді масиву з двома вимірами:
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. Наприклад:
- typeTMySet = 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 .