Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
основы программирования на Паскале.doc
Скачиваний:
255
Добавлен:
25.03.2016
Размер:
4.34 Mб
Скачать

19. Множества и перечислимые типы

Материал этой и последующих глав учебника является отчасти "факультативным", он может выходить за пределы, предусмотренные "программой-минимум" изучения основ программирования, однако, для тех, кто собирается программировать всерьез, тщательное изучение этих глав будет весьма полезным.

Множествапредставляют собой заранее заданные программистом наборы возможных значений переменной. Применение множеств позволяет удобно обращаться с данными, имеющими фиксированный набор возможных значений, а также облегчает проверку того, попадают ли значения в нужный диапазон.000000000000000000000000000000000000000000000000000000

Для объявления множества достаточно записать оператор

Set of тип;

где тип– один из определенных программистом или предустановленных типов данных:

Type Charset: set of Char;

Var Symbols: Charset;

Вопреки этому примеру, стандартные типы данных мало применимы для множеств – ведь исходный тип набора должен быть порядковым(см. раздел 2.3) и не иметь более, чем 256 различных значений с нижним и верхним пределом от 0 до 255 соответственно. Это связано с тем, что для хранения количества элементов множества выделяется только один байт оперативной памяти. Приведем другой пример для множества:

type Charset= set of char;

var symbols:Charset;

c1:Char;

begin

symbols:=['A'..'Z','a'..'z'];

write ('Put one symbol:');

readln (c1);

if c1 in symbols then writeln ('OK')

else writeln ('Error');

end.

Из примера видно, что переменным типа множества можно присваивать список диапазонов соответствующего типа (мы уже знакомились с диапазонами в разделе 7.8). В дальнейшем переменная типа множества может быть использована для контроля правильности входных данных с помощью оператора in:

if c1 in symbols then writeln ('OK')

Слева от оператора inможет быть указано выражение любого перечислимого типаT, а справа – набор с типом, совместимым с типомT.

Любые совместимые по типам данных множества можно объединять операций "+", вычитать операцией "-" и пересекать операцией "*". При этом результаты операций с множествами соответствуют правилам логики множеств:

  • порядковое значение Cнаходится в множествеA+Bтолько в том случае, еслиCнаходится вAилиB;

  • порядковое значение Cнаходится в множествеA-Bтолько в том случае, еслиCнаходится вAи не находится вB;

  • порядковое значение Cнаходится в множествеA*Bтолько в том случае, еслиCнаходится и вA, и вB.

Если самое маленькое порядковое значение, являющееся элементом результата операции с множеством обозначить A, а самое большое - заB, то тип результата становится равнымA..B.

В следующем примере множество латинских букв получается операцией сложения подмножеств латинских больших и латинских малых букв.

Type Latin = Set Of 'A'..'z';

Const SmallLatin : Latin = ['A'..'Z'];

BigLatin : Latin = ['a'..'z'];

Var LatinLetters : Latin;

c:char;

begin

LatinLetters := BigLatin + SmallLatin;

repeat

write ('Введите символ или пробел для выхода:');

reset (input);

readln (c);

if c in LatinLetters then writeln (c,' - латинская буква');

until c=' ';

end.

Как в примере выше, полезно бывает создавать из множеств подмножествапри указанииконструктора, содержащего выражения диапазонов в квадратных скобках[…]:

Type Digits = Set Of 0..9; {Множество цифр}

Letters = Set Of 'A'..'Z'; {Множество латинских букв}

Const EvenDigits : Digits = [0, 2, 4, 6, 8];

{Подмножество четных цифр}

Vowels : Letters = ['A', 'E', 'I', 'O', 'U', 'Y'];

{Подмножество гласных букв}

HexDigits : Set Of '0'..'z' = ['0'..'9', 'A'..'F',

'a'..'f']; {Символы 16-ричных чисел}

Type ShortWeekDays = (Pn,Vt,Sr,Ch,Pt,Sb,Vs);

{Перечислимый тип "дни недели"}

Const Holidays : Set of ShortWeekDays = [Sb, Vs];

{Подмножество "Выходные" дней недели}

Var wd:ShortWeekDays; {Переменная типа "Дни недели"}

i:integer;

begin

wd:=Pn;

for i:=1 to 7 do begin

if wd in Holidays then writeln (Ord(wd), ' - Выходной день')

else writeln (Ord(wd), ' - Будний день');

Inc(wd);

end;

end.

Тип данных ShortWeekDaysв этом примере являетсяперечислимымтипом. Перечислимые типы определяют упорядоченные наборы значений, перечисляя идентификаторы, которые обозначают эти значения. Их порядок следует из последовательности, в которой они были перечислены. Оператор перечисления имеет общий вид

Type имя = (идентификатор, идентификатор,..., идентификатор);

Возможные значения перечисления, заданные оператором Type, должны быть идентификаторами Паскаля, поэтому назвать дни недели по-русски в последнем описанииTypeбыло бы невозможно.

Идентификаторы, указанные в определении типа, становятся константами перечислимого типа, первая константа имеет порядковый номер 0, вторая – номер 1, и так далее:

Type Suit = (Club, Diamond, Heart, Spade);

При этом объявлении Heartявляется константой типаSuit. Стандартная функцияOrdвозвращает порядковый номер перечислимой константы, в нашем примере

Ord(Club) = 0

Ord(Diamond) = 1

Ord(Heart) = 2

Как показано в листинге, переменным перечислимого типа можно присваивать константы, входящие в описание типа и увеличивать их значения как любые порядковые числа оператором Inc(wd), но эти значения нельзя читать или записывать "напрямую" операторами семействаRead/Write. В качестве альтернативы их можно приводить к целочисленным значениям стандартной функциейOrd, при этом всегда первая константа списка имеет значение0(в нашем случае – константаPn). Операторinв листинге позволяет проверить, попадает ли величина в подмножество, созданное для элементов исходного типа множества. Таким образом, основное назначение множеств и перечислимых типов – удобная для человека запись выражений с "понятными" названиями констант вместо чисел. С точки зрения компилятора данные типа множества и перечисления являются целочисленными величинами.

Для ограничения диапазона исходных данных можно также непосредственно объявить тип-диапазон:

Type Hour=0..23; Minute=0..59;

Здесь объявлены переменные типов “час“ и “минута“, для переменных этих типов будут проверяться ограничения на попадание в указанные при описании диапазоны значений. Если переменной типа-диапазона присвоено недопустимое значение, программа отреагирует на это сообщением “Constantoutofrange”.