type birthday = record
day: 1..31;
month: 1..12;
year: word;
end;
person = record
name: string[20];
data: birthday;
end;
var sasha: person;
Обращение: sasha.data.day := 17;
При работе с комбинированными типами чтобы упростить доступ к полям записи, используют оператор присоединения.
with <имя переменной> do <оператор>;
with sasha.data do begin
day := 17;
month := 7;
year := 1997;
end;
Множественные типы.
Множество – это совокупность объектов.
type Digit = set of 1..5;
var s: Digit;
Значение множественного типа может содержать любое количество различных элементов – от 0 до всех возможных значений. Тип, которому должны принадлежать все элементы множества, называется базовым типом. Если базовый тип, на котором строится подмножество, имеет kэлементов, то количество подмножеств, входящих в этот множественный тип, равно 2^k.
x: 1..3;
z: setof 1..3;
zможет быть пустым множеством или иметь значения: 1; 2; 3; 1 и 2; 1 и 3; 2 и 3; 1, 2 и 3.
В качестве базового типа множества может использоваться любой порядковый тип, кроме типов Word, Integerи Longint. Множество не может содержать больше, чем 256 элементов. Переменная множественного типа занимает 32 байта. Множество – это бесповторная, неупорядоченная совокупность объектов.
type ElemColor = (red, yellow, green);
Color = set of ElemColor;
var mycolor: Color;
В Паскале для изображения множества используется конструктор множества – список элементов множества, заключённый в квадратные скобки.
mycolor := [] или mycolor := [red, green]
Два множества считаются эквивалентными тогда и только тогда, когда все их элементы одинаковы, причём порядок следования элементов безразличен. Если все элементы одного множества входят также и в другое, говорят о включении первого множества во второе.
Операции над множествами:
1) Пересечение (*). Результат операции – множество, содержащее элементы, общие для обоих множеств.
A = [0..3, 6]
B = [3..9]
C := A * B; C = [3, 6]
2) Объединение (+). Результат – множество, состоящее из элементов, принадлежащих и A, и B.
A + B = [0..9]
3) Вычитание (-). Результат – множество, состоящее из тех элементов первого множества, которые не входят во второе.
A – B = [0..2]
4) Операция проверки принадлежности элемента множеству.
<выражение> in <множество>
var st: string;
a: set of 0..9;
k, i: integer;
begin
readln(st);
k := length(st);
a := [0..9];
for i := 1 to k do
if st[i] in a then write(st[i]);
writeln;
for i := 1 to k do
if not (st[i] in a) then write(st[i]);
end.
Кроме рассмотренных операций, к множествам применимы операции отношения: =, <>, <=, >=.
В Паскале отсутствует механизм изъятия элемента из множества.
var s: set of char;
for i := 0 to 255 do
if chr(i) in s then inc(c);
Эквивалентность и совместимость типов.
В языке Паскаль принят принцип именной эквивалентности. Два типа T1 и T2 являются эквивалентными, если выполняется одно из двух условий: 1) T1 и T2 представляют собой один и тот же идентификатор; 2) Тип T2 описан с использованием типа T1 с помощью непосредственного неравенства вида T2 = T1, либо посредством цепочки неравенств: T2 = T1, T3 = T2 и т.д.
type A1 = array[1..10] of integer;
A2 = array[1..10] of integer;
Но типы A1 и A2 неэквивалентны.
V1, V2 = array[1..10] of integer;
V1 и V2 – эквивалентные типы.
Эквивалентность типов требуется при выполнении оператора присваивания над массивами, а также в случае передачи параметров при вызове процедур или функций (то есть типы фактических и формальных параметров должны быть эквивалентны).
Выполнение операций выражений и сравнения требует, чтобы операнды имели совместимые типы.
Два типа считаются совместимыми, если выполняется одно из следующих условий: 1) два типа эквивалентны; 2) оба типа являются целыми, либо оба – вещественными; 3) один тип является ограниченным типом, причём его базовым типом является другой тип; 4) оба типа являются ограниченными, причём их базовым типом является один и тот же тип; 5) оба типа являются множественными типами, причём их базовые типы совместимы; 6) оба типа строковые, либо один тип строковый, а другой – символьный; 7) оба типа ссылочные.
Оператор присваивания считается корректным, если тип переменной в левой части совместим с типом выражения в правой части. Типы совместимы по присваиванию при выполнении хотя бы одного из следующих условий: 1) оба типа эквивалентны, и ни один из них не является файловым или структурным типом, содержащим поле с файловым типом; 2) оба типа являются совместимыми дискретными типами, и значение типа в правой части попадает в диапазон возможных значений типа в левой части; 3) оба типа вещественные, и значения из правой части попадают в диапазон возможных значений из левой части; 4) слева – переменная вещественного типа, справа – выражение целого типа; 5) слева – строковый тип, справа – символьный, либо строковый; 6) оба типа – совместимые множественные типы; 7) оба типа являются совместимыми ссылочными типами.
Преобразование типов.
В Паскале данные одного типа могут преобразовываться в данные другого типа. Такое преобразование может быть явным и неявным.
Неявное преобразование – возможно в присваивании. Например, когда вещественной переменной присваиваются целые значения. Кроме того, неявное присваивание встречается в выражениях с переменными смешанных типов.
При явном преобразовании типов используются вызовы специальных функций преобразования, аргументы которых принадлежат одному типу, а значения – другому. Например, функция Odd(i), функция Chr(j), функции Round(x), Trunc(x). Кроме того, в Паскале есть специальная конструкция явного преобразования типа. Называется она «приведение типа переменной». Тип (имя_перем).
si: 0..255;
char(si) := ‘z’;
Конструкция приведения типа переменной может находиться везде, где допускается вхождение переменной. Близкой по синтаксису является конструкция приведения типа значения, которая позволяет преобразовать тип произвольного выражения, записанного в круглых скобках, к типу перед скобками. Тип (выражение). Конструкция может встречаться везде, где допустимо выражение, например, справа от символа присваивания.
Li: Longint;
i: integer;
Li := 1234567;
i := integer(Li + 1);
Но такое преобразование может привести к усечению типа значения. Тип выражения в скобках и идентификатор выражения перед скобками должны являться оба дискретными типами. Если один дискретный тип преобразуется к другому, то такое преобразование может привести к усечению или увеличению размера памяти по сравнению с исходным. Если значение расширяется, то его знак всегда сохраняется.
Файловые типы в Паскале и ввод-вывод.
Под файлом понимается именованная область внешней памяти ЭВМ или логическое устройство. В файл данные можно записать, либо извлечь. Эти действия имеют общее название «ввод-вывод». Для осуществления операции ввода-вывода с файлами, в программе необходимо определить переменные файловых типов, которые считаются представителями файлов в программе. Файл при этом рассматривается как бесконечный список значений. В Паскале существует три типа файловых переменных: типизированные файлы, текстовые и нетипизированные файлы.
var fp: file of <тип>;
fp: file of real; - типизированные файлы
fp1: text; - текстовые файлы
fp2: file; - нетипизированные файлы
С каждой переменной файлового типа связано понятие текущего указателя файла. Все элементы файла считаются пронумерованными, и начальный элемент имеет нулевой номер.
Операции над файлами.
Input– файл для считывания данных с клавиатуры.
Output– файл для вывода данных на экран.
Для того чтобы работать с файлом на внешнем носителе, в программе необходимо: 1) описать файловую переменную; 2) связать файловую переменную с файлом на диске. Это осуществляется с помощью процедуры: Assign(fp, ‘<cтрока, задающая имя файла>’);
Assign(fp, ‘D:\MyDir\data.dat’);
3) открыть файл. В Паскале файл можно открыть только для чтения, только для записи. Типизированные файлы можно открыть и для чтения, и для записи одновременно. Для открытия файлов служат две процедуры: Reset(fp) – на чтение; Rewrite(fp) – на запись.
Под открытием файла понимается поиск файла на внешнем носителе, образование специальных буферных областей в памяти для работы с ним и установка текущего указателя на начало файла. Процедура Resetпредполагает, что дисковый файл существует. Процедура Rewriteдопускает, что указанный файл может не существовать. В этом случае процедура создаёт на диске файл с тем именем, которое указали в процедуре Assign. Для закрытия файлов существует процедура Close(fp); Она закрывает файл, однако связь с файловой переменной не разрывается.
Операции ввода-вывода.
Для осуществления ввода-вывода из файла существуют две процедуры: Readи Write.
Read([<ф.пер.>], список ввода);
Write([<ф.пер.>], список вывода);
Список ввода – это последовательность из одного или более имён переменных типа char, string, а также любого целого или вещественного типа. В эти переменные будут помещаться значения из файла.
Список вывода – это список выражений. Выражения также разделяются запятыми.
И чтение из файла, и запись в файл производится в позицию, в которой находится текущий указатель файла. После ввода-вывода текущий указатель перемещается.
Некоторые процедуры и функции для работы с файлами.
Rename(<ф.пер.>, ‘<новое имя файла>’) – переименовать файл. Перед выполнением процедуры файл необходимо закрыть, если он был открыт.
Erase(<ф.пер>) – удаляет файл.
EOF(<ф.пер.>): Boolean – функция проверяет, достигнут ли указателем конец файла.
IOResult: Word – возвращает условный признак последней операции ввода-вывода. Если операция открытия файла прошла успешно, функция возвращает 0, и не 0 в противном случае. Для использования функции необходимо отключить контроль ошибок ввода-вывода. Директива {$I-} перед открытием файла отключает контроль ошибок. После проверки лучше снова включить контроль ошибок директивой {$I+}.
var f: file of char;
…
begin
assign(f, ‘Myfile.dat’);
{$I-}
Reset(f);
{$I+}
if IOResult <> 0 then writeln(‘Файл не существует’)
else …
Текстовые файлы.