…
End.
Обратиться к полю записи можно указав сначала идентификатор переменной-записи, а затем через точку – имя поля (на примере). Независимо от количества объявленных переменных данного типа, поля каждой из них будут называться одинаково (D1.X, D2.X). Кроме того, поскольку имена полей «скрыты» внутри переменной, они могут дублировать обычные перменные (X и D1.X).
Альтернатива введению специального типа состоит в описании записи непосредственно в разделе Var.
Переменная типа запись может участвовать в операциях присваивания, если они относятся к одному и тому же типу: D1 := D2;
Поле записи может иметь практически любой тип, в том числе и другую запись (вложенные структуры).
Var
D : record
X : integer;
R : record
RX : integer;
RZ : char
end
end;
Begin
…
D.R.RX := 2;
…
End.
Чтобы упростить доступ к полям записи, используется оператор присоединения WITH со следующим форматом:
with <имя переменной-записи> do <оператор>
Внутри оператора (стоит после do, может быть составным) обращение к полям записи уже производится без указания идентификатора самой переменной. Например,
with D do
begin
R.RX := 2; R.RZ := ‘f’;
end;
ЗАПИСИ С ВАРИАНТАМИ
В ТР можно использовать запись с т.н. вариантными полями. Например,
Var
D : record
X : integer;
case V: boolean of
True : (Y_one : integer);
False : (Y_two : array [1..4] of real)
end;
Здесь поле Х – фиксированно. Второе поле V – это поле признака, которое может иметь два значения True и False. Третье поле будет иметь разные варианты в зависимости от значения поля V (либо D.Y_one либо D.Y_two). Вариантное поле м.б. только одно, записывается в конце. В любое время доступны поля только одного из вариантов.
Записи можно считать некоторой ступенью к структурам типа объектов.
МНОЖЕСТВА
Множество – это структурированный тип данных, представляющий собой набор взаимосвязанных по какому-либо признаку, или группе признаков элементов, которые можно рассматривать как единое целое. Количество элементов, входящих в множество, может меняться в пределах от 0 до 256 (множество, не содержащее элементов называется пустым). Два множества считаются эквивалентными, если все их элементы одинаковы, причем порядок следования элементов в множестве безразличен.
Описание типа множества имеет вид:
<имя типа> = set of <базовый тип>
<базовый тип> - любой порядковый тип с числом элементов <= 256 (кроме Word, Integer, Longint). Например,
Type
TypeSet1 = set of Char; {множество из символов}
TypeSet2 = set of 0..9; {множество чисел от 0 до 9, базовый тип – тип-диапазон}
VideoType = (Hercules,CGA,EGA,VGA,SVGA); {заранее описывается перечисляемый тип}
TypeSet3 = set of VideoType; {множество из названий видеоадаптеров}
Если переменная описана как множество, она подчиняется специальному синтаксису. Значение такой переменной задается перечислением элементов базового типа (т.е. того типа, который фигурирует при задании типа переменной) через запятую в квадратных скобках:
Var
Set1 : set of Byte;
Set2 : set of ‘a’..’f’;
Begin
…
Set1 := [1,2,6];
Set1 := [3..10,12];
Set2 := [‘a’,’d’];
…
End.
Пустое множество записывается как []. Порядок следования элементов внутри скобок не имеет значение, также как не имеет значение число повторений (множества [1,2] [2,2,1] эквивалентны). Над множествами определены следующие операции:
* пересечение множеств, результат содержит элементы общие для обоих множеств (Set1 := [0..3,6]; Set2 := [3..9]; Set1*Set2 = [3]);
+ объединение множеств, результат содержит элементы первого множества, дополненные недостающими элементами второго (Set1+Set2 = [0..9]);
- разность множеств, результат содержит элементы первого множества, которые не принадлежат второму (Set1-Set2 = [0,1,2]);
= проверка эквивалентности (логическая операция, как и последующие), возвращает True, если оба множества эквивалентны;
<> проверка неэквивалентности, возвращает True, если множества неэквивалентны;
<= проверка вхождения, возвращает True, если первое множество включено во второе (т.е. все элементы первого множества содержаться во втором);
>= проверка вхождения, возвращает True, если второе множество включено в первое;
in проверка принадлежности (E in S), возвращает True, если значение Е входит в множество S и принадлежит базовому типу этого множества, Е может быть выражением (3 in Set1 дает True, 2*2 in Set1 дает False).
Естественно, что в рассмотренных операциях могут участвовать только те множества, которые построены на одном базовом типе.
Операции над множествами дополняют две процедуры:
INCLUDE (S,I) - включает новый элемент I в множество S, включаемый элемент должен принадлежать базовому типу множества S.
EXCLUDE (S,I) - исключает элемент I из множества S.
В отличие от операций + и -, реализующие аналогичные действия над двумя множествами, процедуры INCLUDE и EXCLUDE оптимизированы для работы с одиночными элементами множеств и поэтому отличаются большей скоростью выполнения.
Достоинства множеств - гибкость представления наборов значений и удобство анализа. Механизм работы с множествами в ТР соответствует базовым математическим действиям с конечными множествами. Значение типа "множество" очень компактно кодируется (для множества из 256 элементов требуется всего 32 байта). Множества хорошо работают, где нужно проводить анализ однотипных выборок значений или накапливать произвольно поступающие значения. Недостатки - невозможно выводить на экран (отладчик это делает). Внутреннее устройство множества таково, что каждому его элементу ставится в соответствие один двоичный разряд (один бит); если элемент включен в множество соответствующий разряд равен 1, если нет - 0. Однако минимальной единицей памяти является байт (8 бит). Поэтому мощность множества кратна 8 элементам (т.е. описав Set1 : set of 0..4, мы можем добавлять в него числа 5,6,7).
СТРОКИ
Тип String в ТР широко используются для обработки текстов и трактуется как цепочка символов. Максимально возможная длина строки 255 символов. Тип объявляется как String[N], где N - максимальное число символов в строке. Строки являются динамическими, поскольку могут иметь различные длины в пределах объявленных границ. Например,
Var
S32 : String[32];
S255 : String[255];
Begin
…
S32 := 'Это строка';
…
End.
позволяет хранить в S32 строчные значения, длиной не более 32 символов (в S255 не более 255). Допустимо описание Var S : String; что равнозначно String[255].
К любому символу в строке можно обратиться точно также, как к элементу одномерного массива array [0..N] of Char. Например, S32[3] := 'а'; Первый значащий символ в строке имеет индекс 1. Индекс 0 имеет символ, код которого равен длине строки (ORD(S32[0]) = 10, пробел является обычным символом, его код = 32).
К строкам можно применить операцию сцепления "+" (S32 := S32 + '!!!').
Существуют стандартные функции и процедуры, реализующие необходимые действия над строками.
LENGTH (S : String) : Byte – выдает длину строки (функция);
CONCAT (S1, S2,…,Sn) : String – возвращает конкатенацию (слияние) строк S1…Sn (функция);
COPY (S : String; Start, Len : Integer) : String – возвращает подстроку длиной Len, начинающуюся с позиции Start строки S (функция);
DELETE (Var S : String; Start, Len : Integer) – удаляет из S подстроку длиной Len, начинающуюся с позиции Start строки S (процедура);
INSERT (Var S, SubS : String; Start : Integer) – вставляет в S подстроку SubS, начиная с позиции Start (процедура);
POS (SubS, S : String) : Byte – ищет вхождение подстроки SubS в строке S и возвращает номер первого символа SubS в S или 0, если SubS нет в S (функция);
Процедуры преобразования
STR (X; Var S : String) – преобразует числовое значение Х в строковое S, возможно задание формата для Х (Str(X:F:n,S) – F – общая ширина поля, n – количество символов в дробной части для вещественных чисел) (процедура);
VAL (S : String; Var X; Var Code : Integer) – преобразует строковое значение S (строку цифр) в значение числовой переменной (Х – целое или вещественное, параметр Code содержит ноль, если преобразование прошло успешно, в противном случае он содержит номер позиции в строке, где обнаружен ошибочный символ, при этом Х не меняется) (процедура).
Имеется возможность применить операции отношения (= <> > < >= <=) к двум строкам. При этом сравнение строк производится посимвольно, начиная с первого символа в строке. Строки равны, если имеют одинаковую длину и посимвольно эквивалентны. Если при посимвольном сравнении окажется, что символ первой строки больше символа второй (имеется в виду их коды), то первая строка считается большей. Остатки строк и их длины не играют роли. Любой символ больше «пустого». Например, 'aBcd’ < ‘ab’, т.к. ‘B’ (код 66) < ‘b’ (код 98).
Особенности оставшихся типов (файлы, указатели, процедурные и объекты) будут рассмотрены в соответствующих разделах позднее.
СОВМЕСТИМОСТЬ И ПРЕОБРАЗОВАНИЕ ТИПОВ
Если в программе объявлены переменные, то подразумевается, что они будут получать свои значения по ходу ее выполнения. Способ поместить значение в переменную – это использовать операцию присваивания:
Переменная := Значение;
Оператор присваивания – это составной символ «:=» (становится равным). В операции присваивания слева стоит имя переменной, а справа – то, что представляет собой ее значение (значение как таковое (константа), выражение, вызов функции, другая переменная). После выполнения операции присваивания переменная получает новое значение.
ТР, являясь языком с сильной системой типов, требует соблюдения определенных правил совместимости типов переменных и значений слева и справа от оператора присваивания.
Очевидно, что не может быть проблем с присваиванием, если типы переменной и значения идентичны (тождественны). Два типа считаются тождественными, если
1. Они описаны вместе, либо одним и тем же идентификатором типа, например
Type
T1 = Boolean;
T2 = Boolean;
T3, T4 = array[1..2] of Real;
Если T1 = array [1..2] of Real и T2 = array [1..2] of Real, то Т1 и Т2 не будут идентичными поскольку конструкции array .. of .. хоть и одинаковые, но не являются идентификаторами, т.е. именами.