http://sulfurzona.ru/
News
Service
Magazine
Software (Battle City Game, Wallpaper manager, Superpad, VG-NOW, Puzzle Game, Netler Internet Browser, ..)
Wing-Thunder Game (fly simulator)
Dune Game (Dune III, Dune IV, Cheats, Forum, ..)
Games free
Turbo Pascal (Assembler, Docs, Sources, Debbugers, ..)
Books (Docs for developers)
Guest book
Компьютерная диагностика двигателя автомобиля (адаптер К-линии)Компьютерная диагностика двигателя автомобиля (адаптер К-линии)
 
 
Скачать игру Крыло-Гром (Wing-Thunder) бесплатно
 
 

Паскаль для новичков (часть 8)

Множественные типы

 
 
Автор: Владислав Демьянишин
 
Паскаль для новичковПришло время рассказать о множественных типах.
Множественные типы принадлежат к несколько непривычным и сравнительно редко используемым средствам языка Pascal. Однако в ряде случаев использование множественных типов позволяет заметно повысить компактность и наглядность программ.
 
Значения множественного типа, так же, как и массивы, строятся из нескольких значений одного (базового) типа. Однако, в отличие от массивов и записей, значение множественного типа может содержать ЛЮБОЕ количество РАЗЛИЧНЫХ элементов базового типа – от нуля элементов (пустое множество) до всех возможных значений базового типа. Иными словами, возможными значениями переменных множественного типа является ВСЕ ПОДМНОЖЕСТВА значений базового типа.
 
Множественный тип задается с помощью двух служебных слов – set и of – и следующего за ним базового типа. Например:
 
type
   TDigits = set of 1..5;
var
   S : TDigits;
 
Переменная S может принимать значения, состоящие из следующих совокупностей (комбинаций) целых чисел:
 
<пусто>
1
1, 2
1, 2, 3
1, 5
1, 3, 4, 5
3, 4, 5
1, 2, 3, 4, 5
 
Хочу обратить внимание на два обстоятельства. Во-первых, все значения базового типа, образующие значения множественного типа, должны быть РАЗЛИЧНЫ. Во-вторых, порядок “расположения” элементов в множестве никак НЕ ФИКСИРУЕТСЯ. Это соответствует принятой в математике трактовке множества как неповторяющейся неупорядоченной совокупности (последовательности ) объектов.
 
Возможно, у читателя возникнет вопрос, из каких значений можно строить множество или, иными словами, каков может быть базовый тип множества. Отвечу. Авторская версия языка ограничивается дискретными типами, однако, практически все реализации сильно сужают это ограничение. Так, Turbo Pascal допускает в качестве базовых типов для множества дискретные типы не более чем с 256 различными значениями, причем (для целых типов) эти значения должны лежать в диапазоне 0..255. Таким ограничениям удовлетворяют только стандартные типы byte и char, перечислимые типы, а также ограниченные типы, образованные от них. Таким образом, диапазон значений множественного типа может состоять ТОЛЬКО из целых положительных чисел.
Приведу еще один пример описания множества:
 
type
   TElemColor = ( Red, Yellow, Blue );
   TColor = set of TElemColor;
var
   MyColor : TColor;
 
Совокупность допустимых значений переменной MyColor содержит следующие множества:
 
<пустое множество>
Red
Yellow
Blue
Red, Yellow
Red, Blue
Yellow, Blue
Red, Yellow, Blue
 
В Pascal-программе допускаются явные изображения значений множественных типов, подобно изображениям целых или вещественных чисел. Изображение множества (или конструктор множества) строится из списка элементов множества, разделенных запятыми. Весь список заключается в квадратные скобки, например:
 
[ ] {пустое множество}
[ 1, 2, 5 ]
[ Red, Yellow ]
 
В качестве элементов в изображении множества допускаются выражения, тип которых должен совпадать с базовым типом множества. Кроме того, можно указать диапазоны значений, составляемые из пары граничных значений, разделенных знаком ‘..’
(две точки); например, два изображения множеств
 
[ 1..3, 5 ] и [ 1, 2, 3, 5 ] эквивалентны.
 
Необходимо помнить, что множество – это бесповторная совокупность элементов, так что, например, следующие три образования обозначают одно и тоже множество:
 
[ 1, 2, 3 ]
[ 1, 1, 2, 3 ]
[ 1, 2, 3, 2, 2, 3, 1 ]
 
Вот еще примеры описаний и изображений множеств.
 
type
   TSetOfChar = set of char;
   TDigits = set of 0..100;
var
   MyChars : TSetOfChar;
   MyDig1, MyDig2 : TDigits;
   x, y : byte;
 
begin
MyChars := [ ‘a’..’z’, ‘0’..’9’, ‘-’ ];
MyDig1 := [ ];
MyDig2 := MyDig1;
MyDig1 := [ x..x+10, 0, y-1, y+1 ];
end.
 
Полезность того или иного типа данных определяется, в первую очередь, набором допустимых операций над значениями этих типов. Что касается множеств, то здесь имеются следующие группы операций:
1) теоретико-множественное объединение, пересечение и вычитание множеств;
2) проверка принадлежности элемента множеству;
3) проверка на равенство и неравенство множеств;
4) проверка на вхождение (принадлежность) одного множества в другое.
 
Теперь расскажу подробнее.
 
1) Объединение, пересечение и вычитание множеств. Эти операции обозначаются, соответственно, символами ‘+’, ‘*’ и ‘-’ и означают традиционные действия с множествами, принятые в математике. Если представить два множества A и B в виде прямоугольников, то множества-результаты перечисленных операций можно наглядно изобразить с помощью закрашенных частей этих прямоугольников:
 
На рис 1 показано объединение множеств: A + B – множество, состоящее из элементов, принадлежащих множествам A и B.
 
Рис. 1
 
На рис 2 показано пересечение множеств: A * B – множество, состоящее из элементов, принадлежащих одновременно и множеству A, и множеству B.
 
Рис. 2
 
На рис 3 показано вычитание множеств: AB – множество, состоящее из тех элементов множества A, которые не принадлежат множеству B.
 
Рис. 3
 
Таблица 1. иллюстрирует приведенные операции.
Операции над множествами
Результат
[ 1, 2 ] + [ 3, 4 ]
[ 1..10 ] + [ 5..15 ]
[ 1..10 ] * [ 5..15 ]
[ 1, 2 ] * [ 3, 4 ]
[ 1..10 ] – [ 5..15 ]
[ 1, 2, 3, 4 ]
[ 1..15 ]
[ 5..10 ]
[ ]
[ 1..4 ]
2) Проверка принадлежности множеству. Эта логическая операция обозначается служебным словом in. Правый операнд должен быть множеством, левый – значением базового типа множества. Операция возвращает true, если значение входит во множество, и false в противном случае. Например, следующие выражения
 
2 in [ 1..10, 12 ]
5 in [ 1, 2, 7, 10 ]
 
возвращают соответственно true и false.
Операцию проверки принадлежности удобно использовать для исключения более сложных проверок. Например, оператор вида
 
var
  S : string;
  ch : Char;
 
begin
if (ch=’a’) or (ch=’b’) or (ch=’x’) or (ch=’y’) then S := S + ch;
 
может быть переписан в гораздо более компактной и наглядной форме:
 
if ch in [ ‘a’, ‘b’, ‘x’, ‘y’ ] then S := S + ch;
 
Замечу, что второй вариант более эффективен с точки зрения быстродействия.
 
3) Проверки на равенство, неравенство и включение множеств. Это бинарные операции также имеют теоретико-множественный смысл и обозначаются следующими знаками:
 
= равенство (совпадение) двух множеств
<> неравенство множеств
<= проверка на вхождение множества из левого операнда во
множество из правого операнда
>= проверка на вхождение множества из правого операнда во
множество из левого операнда
 
Все эти операции вырабатывают логическое значение true или false в зависимости от успеха проверки. Вот примеры:
 
[ 1, 2, 3 ] = [ 1, 2 ] { вернет false}
[ 1, 2, 3 ] >= [ 1, 2 ] { вернет true}
[ S ] <= [ 1..10 ] { вернет true, если S – целое число из
диапазона 1..10}
[ 1, 2, 3 ] <> [ 1, 2, 4 ] { вернет true}
 
Хочу отметить, что все операции над множествами работают достаточно эффективно, поэтому имеет смысл применять их всюду, где это необходимо. К сожалению, набор операций над множествами в Pascal’е не содержит, по крайней мере, одной практически важной операции – выборки значения из множества (или близко связанного с ней средства циклического перебора значений множества). Поэтому при необходимости подобных действий приходится организовывать цикл по всему диапазону значений базового типа, проверяя на каждой итерации принадлежность очередного значения данному множеству.
 
Предположим, что в ходе работы программы формируется некоторое множество посредством сложения, умножения, вычитания различных множеств. И в итоге необходимо проанализировать полученное в результате множество таким образом, чтобы все значения, входящие в это множество, вывести на экран. Хотя на практике может понадобиться работа и по сложнее, но для наглядности я предлагаю такой вариант.
 
var
  Symbols: set of char;
  S : Char;
 
begin
Symbols := [ 'a', 'b', 'c' ];
Symbols := Symbols + [ 'd', 'e', 'f' ];
Symbols := Symbols * [ 'a', 'd', 'e', ‘h’ ];
write('Symbols = [ ');
for S := chr(0) to chr(255) do
if S in Symbols then write(S, ' ');
writeln(']');
end.
 
На экране получим результат [ a d e ].
Надо сказать, что переменная Symbols занимает 32 байта. Размер занимаемой памяти переменной типа множество зависит от количества элементов в базовом типе этого множества. Т.е. на каждый элемент отводится один бит памяти. Следовательно, для переменной Symbols количество элементов 255 делим на 8 (так как в байте 8 бит) и получаем 32 байта.
 

Операторы

 
Операторы в языке Pascal – это синтаксические конструкции, предназначенные как для записи алгоритмических действий по преобразованию данных, так и для задания порядка выполнения других действий.
 
Набор операторов языка Pascal составляет минимальное множество конструкций, необходимых для наглядного однозначного представления алгоритмов в стиле структурного программирования.
Язык содержит следующие операторы:
1) оператор присваивания;
2) оператор процедуры;
3) оператор перехода;
4) составной оператор;
5) условный оператор;
6) оператор варианта;
7) оператор цикла с предусловием;
8) оператор цикла с постусловием;
9) оператор цикла с параметром;
10) оператор над записями;
11) пустой оператор.
 
Первые три оператора считаются простыми, остальные – структурными. Последнее означает, что в состав этих операторов могут входить другие операторы. Можно сказать, что структурные операторы задают некоторое правило выполнения операторов, входящих в их состав.
 
Операторы, входящие в структурные, в свою очередь, могут быть структурными. “Глубина вложенности” операторов не ограничивается.
Любому оператору может предшествовать метка. В этом случае метка отделяется от оператора символом ‘:’ (двоеточие). Метки можно использовать для передачи управления на помеченные операторы других точек программы (см. раздел “Оператор перехода”).
 
Помимо перечисленных операторов языка Pascal, язык Turbo Pascal содержит два оператора специального вида:
1) машинный код;
2) ассемблерный оператор.
 
С помощью операторов первого вида можно включать в
программу фрагменты, составленные из команд центрального процессора. Ассемблерный оператор позволяет записывать отдельные части Pascal-программ с использованием языка ассемблера (см. главу “Программирование на низком уровне”).
 

Оператор присваивания

 
Данный оператор является простейшим и наиболее часто употребляемым оператором языка. Он предназначен для вычисления нового значения некоторой переменной, а также для определения значения, возвращаемого функцией.
 
Оператор выполняется следующим образом. Вычисляется выражение в правой части присваивания. После этого переменная, указанная в левой части, получает вычисленное значение. При этом тип результата выражения должен быть совместим по присваиванию с типом переменной (см. главу “Преобразование типов. Совместимость типов” в номере МК 6(177) от 18.02.2002). Присваивания допускаются для всех типов (в том числе и для массивов, записей и т.д.), КРОМЕ файловых типов.
 
О втором варианте оператора присваивания (с идентификатором функции) я расскажу в главе “Процедуры и функции”.
Вот несколько примеров присваивания:
 
X := ( Y + Z ) / ( 2 + Z * 10 ) – 0.5;
Done := ( i > 100 ) or ( A[ i ] = 0 );
Color := Red;
MySet := [ 1, 7..10, 100 ];
 

Оператор процедуры

 
Этот оператор (называемый также вызовом процедуры) задает выполнение операторов, определенных в теле вызываемой процедуры (см. главу “Процедуры и функции”). После завершения выполнения процедуры управление передается на оператор, следующий за оператором процедуры.
 
Вызов процедуры может сопровождаться передачей значений фактических параметров, если в определении процедуры был указан список соответствующих формальных параметров. Подробное рассмотрение аспектов, связанных с процедурами, я изложу в главе “Процедуры и функции”. Здесь ограничусь только несколькими примерами:
 
Multiply_Matrixes( A, B );
Init_Array( M, i * 3 );
ExitProgram;
 
Продолжение следует…
 
© Владислав Демьянишин
 
 
На нашем сайте можно не только бесплатно скачать игры, но и документацию и книги по программированию на MIDLetPascal, Turbo Pascal 6, Turbo Pascal 7, Borland Pascal, по программированию устройств Sound Blaster, Adlib, VESA BIOS, справочник Norton Guide и много другой полезной информации для программистов, включая примеры решения реальных задач по созданию резидентных программ.
 

Журнал > Программирование > Паскаль для новичков (Turbo Pascal, Assembler) > Паскаль для новичков (часть 8): Множественные типы
 
 
 
 
 
 
На главную страницу На предыдущую страницу На начало страницы