ОР1 містить у собі тіло циклу й оператор зміни параметра циклу. Тому фрагмент приведеної задачі буде мати вигляд:
x=0;
while (2*x*x-5*x<500) do
Begin
y:= 2*x*x-5*x;
x:=x+0.3
End;
Якщо при першому значенні параметра х умова циклу не виконується, то цикл жодного разу не буде виконаний.
2.4.5.4 Цикл із післяумовою
У деяких випадках виникає ситуація, що хоча б один раз цикл повинний бути виконаний при будь-яких умовах. Тоді необхідно використовувати конструкцію виду:
Repeat
OP1;
until (умова виконання циклу);
Вище приведена програма буде записана в такий спосіб:
x=0;
Repeat
y:= 2*x*x-5*x;
x:=x+0.3
until (2*x*x-5*x<500);
У цьому випадку значення у при х=0 буде розраховано обов'язково.
Оператори завершення циклу
Для всіх операторів циклу вихід з циклу здійснюється внаслідок як природного закінчення оператора циклу, так і за допомогою операторів переходу і виходу.
У версії ТУРБО ПАСКАЛЬ 7.0 визначені стандартні процедури Break і Continue. Процедура Break виконує безумовний вихід з циклу. Процедура Continue забезпечує перехід до початку нової ітерації циклу.
2.4.7 Оператор варіанту
Оператор if дозволяє виконувати перехід на ту чи іншу гілку за значенням булевої умови. Використовуючи комбінації з декількох таких операторів, можна робити розгалуження по декількох умовах. Наприклад, визначення кварталу по номеру місяця:
if n<4 then writeln("перший квартал")
else if n<7 then writeln("другий квартал")
else if n<10 then writeln("третій квартал")
else writeln("четвертий квартал");
Принципово задача вирішена, але такий підхід є досить стомлюючим і одноманітним. Паскаль надає для цих цілей іншу керуючу структуру:
Case (виразу) of
значення: оператор 1;
значення: оператор 2;
………………………
значення: оператор k
End;
З використанням цієї конструкції задача визначення кварталу буде вирішена наступним фрагментом програми:
Case n of
1,2,3: writeln("перший квартал");
4,5,6: writeln("другий квартал");
7,8,9: writeln("третій квартал");
10,11,12: writeln("четвертий квартал")
End;
Змінна вибору (селектор) не повинна належати типу real. Якщо селектор приймає значення, якому не відповідає жоден вхід, то конструкція Case буде пропущена зовсім.
Оператори виходу
Для завершення роботи програм, процедур і функцій без попереднього переходу по мітках до закриваючого end у TURBO PASCAL уведені процедури Exit і Halt.
Виклик Exit завершує роботу свого програмного блоку і передає керування викликаючій програмі. Якщо Exit виконується в підпрограмі, то виконання цієї підпрограми припиниться, і далі буде виконуватися наступний за викликом цієї підпрограми оператор. Якщо Exit виконується в основній програмі, вихід з її буде еквівалентний її нормальному завершенню.
Виклик процедури Halt, де б вона не знаходилася, завершує роботу програми і передає керування операційній системі.
Процедура Halt має структуру Halt(n), де n - код повернення, що може бути проаналізований операційною системою за допомогою команди if errorlevel. Значення n=0 відповідає нормальному завершенню роботи програми. Виклик процедури Halt без параметра еквівалентний виклику Halt(0).
2.5 Вбудовані функції
У мові Паскаль мається великий ряд вбудованих стандартних процедур і функцій. При їхньому використанні немає необхідності робити їхній опис. Приведемо найбільш розповсюджені з них:
· Abs(Num) - повертає абсолютне значення (модуль) числа Num. Наприклад, при Num:=-56.7 значення в, обчислене по вираженню у:= Abs(Num), буде 56.7;
· ArcTan(Num) - повертає арктангенс числа Num у радіанах;
· Cos(Num) - повертає значення косинуса кута Num, заданого в радіанах;
· Sin(Num) - повертає значення синуса кута Num, заданого в радіанах. Інші тригонометричні функції обчислюються аналітично через вище приведені;
· Exp(Num) - повертає е Num;
· Frac(Num) - повертає дробову частину числа Num. Знак результату - такий ж, як і Num;
· Int(Num) - - повертає цілу частину числа Num. Знак результату - такий ж, як і Num;
· Sqr(Num) - піднесення числа Num до квадрату;
· Sqrt(Num) - корінь квадратний з числа Num. Значення Num повинне бути додатнім;
· Odd(Num) - приймає булеве значення «ІСТИНА», якщо Num не парне і «НЕПРАВДА» - якщо Num - парне. Наприклад, if Odd(Num) then writeln(‘не парне’) else writeln(‘парне’);
· Chr(Num) - повертає символьне представлення коду. Num повинно бути цілочисленним, наприклад, c:=Chr(65) привласнює символьній змінній с значення «А»;
· Ord(Num) - повертає порядковий номер символу, привласненого символьною змінною Num (зворотна функції Chr);
· Trunc(Num) -перетворення типу даних з real у integer шляхом відкидання дробової частини. Наприклад, якщо а:=67.78; k:=Trunc(a); то k=67;
· Round(Num) -перетворення типу даних з real у integer шляхом округлення до найближчого цілого. Наприклад, якщо а:=67.78; k:= Round (a); то k=68;
· Random(Num) - повертає випадкове речовинне число з діапазону 0÷Num, розподілене по рівномірному закону (ймовірність кожного числа діапазону однакова). Щоб змістити діапазон чисел що генеруються необхідно до кожного одержаного числа додати деяку константу, від’ємну - для зсуву діапазону убік від’ємних чисел, і додатню - вбік збільшення чисел. Наприклад, при
· k:=Random(50); генеруються числа з діапазону 0÷50;
· k:=100+Random(50); генеруються числа з діапазону 100÷150;
· k:=Random(50)-100; генеруються числа з діапазону - 100÷-50;
Для одержання розподілу Симпсона необхідно зробити три звертання до рівномірного генератора і визначити середнє значення:
y:=0;
for i:=1 to 3 do y:=y+Random(100);
y:=y/3;
Для одержання нормального розподілу необхідно зробити десять звертань до рівномірного генератора і визначити середнє значення:
y:=0;
for i:=1 to 10 do y:=y+Random(100);
y:=y/10;
Генератор випадкових чисел Random насправді є генератором псевдовипадкових чисел - при кожному новому запуску програми послідовності що генеруються будуть ті самі. Щоб «збити» генератор перед першим звертанням до нього в програмі необхідно поставити процедуру Randomize.
· KeyPressed - приймає булеве значення «ІСТИНА», якщо була натиснута будь-яка клавіша на клавіатурі і «НЕПРАВДА» - у протилежному випадку. Використовується для зупинки\старту обчислювального процесу.
2.6 Бітова арифметика
Бітова чи поразрядна арифметика введена в TURBO PASCAL для забезпечення можливості роботи з двійковими розрядами (бітами). Операції бітової арифметики застосовують тільки до цілих типів.
Перша група операцій - логічні операції not, and, or і xor.
Операція not є одномісною, вона змінює кожен біт цілого числа на зворотній.
Операції and, or і xor - двомістні, операнди цих операцій - цілі величини однакової довжини. Операції виконуються попарно над усіма двійковими розрядами операндів.
Друга група операцій - це операції зрушення вліво shl і зрушення вправо shr:
I shl N
I shr N.
Ці операції зрушують двійкову послідовність значення I вліво чи вправо на N двійкових розрядів. При цьому біти, що виходять за межі розрядної сітки, губляться, а двійкові розряди, що звільнилися, заповнюються нулями. При зрушенні вправо розряди з від’ємними значеннями, що звільнилися, заповнюються одиницями.
2.7 Завдання типів даних
2.7.1 Тип даних, які перелічуються
Тип, що перелічується, являє собою обмежену упорядковану послідовність скалярних констант, що складають даний тип. Значення кожної константи задається її ім'ям. Імена окремих констант відокремлюються один від одного комами, а вся сукупність констант, що складають даний тип, який перелічується, лягає в круглі дужки.
Програміст поєднує в одну групу відповідно до певної ознаки всю сукупність значень, що складають тип, який перелічується.
Наприклад, тип, що перелічується Rainbow(ВЕСЕЛКА) поєднує скалярні значення RED, ORANGE, YELLOW, GREEN, LIGHT_BLUE, BLUE, VIOLET (ЧЕРВОНИЙ, ЖОВТОГАРЯЧИЙ, ЖОВТИЙ, ЗЕЛЕНИЙ, БЛАКИТНИЙ, СИНІЙ, ФІОЛЕТОВИЙ). Тип, що перелічується, Traffic _ Light (СВІТЛОФОР) поєднує скалярні значення RED, YELLOW, GREEN (ЧЕРВОНИЙ, ЖОВТИЙ, ЗЕЛЕНИЙ).
Тип, що перелічується, описується в розділі опису типів, що починається зі службового слова type, наприклад:
Type
Rainbow = (RED, ORANGE, YELLOW, GREEN, LIGHT_BLUE, BLUE, VIOLET);
Кожне значення є константою свого типу і може належати тільки одному з типів, що перелічуються, заданих у програмі. Наприклад, тип що перелічується Traffic_Light не може бути визначений в одній програмі з типом Rainbow, тому що обидва типи містять однакові константи.
Опис змінних, приналежних до скалярних типів, що оголошені в розділі опису типів, виробляється за допомогою імен типів. Наприклад:
type Traffic_Light= (RED, YELLOW, GREEN);
var Section: Traffic_Light;
Це означає, що змінна Section може приймати значення RED, YELLOW чи GREEN.
Змінні типу, що перелічується, можуть бути описані в розділі опису змінних, наприклад:
var Section: (RED, YELLOW, GREEN);
При цьому імена типів відсутні, а змінні визначаються сукупністю значень, що складають даний тип, що перелічується.
До змінних типу, що перелічується, може бути застосовано оператор присвоювання:
Section:= YELLOW;
Упорядкована послідовність значень, що складають тип, що перелічується, автоматично нумерується, починаючи з нуля і далі через одиницю. Звідси випливає, що до переліка змінних і констант можуть бути застосовані операції відношень і стандартні функції Pred, Succ, Ord.
Змінні і константи типу, що перелічується, не можуть бути елементами списку вводу чи виводу.
Інтервальний тип даних
Відрізок будь-якого порядкового типу може бути визначений як інтервальний чи обмежений тип. Відрізок задається діапазоном від мінімального до максимального значення констант, розділених двома крапками. Як константи можуть бути використані константи, що належать до цілого, символьного, логічного чи типів, що перелічується. Скалярний тип, на якому будується відрізок, називається базовим типом.
Мінімальне і максимальне значення констант називаються нижньою і верхньою границями відрізка, що визначає інтервальний тип. Нижня границя повинна бути менше верхньої.
Над змінними, які відносяться до інтервального типу, можуть виконуватися всі операції і застосовуватися всі стандартні функції, що допустимі для відповідного базового типу.
При використанні в програмах інтервальних типів даних може здійснюватися контроль за тим, щоб значення змінних не виходили за границі, введені для цих змінних в описі інтервального типу.
Масиви
Масиви являють собою обмежену упорядковану сукупність однотипних величин. Кожна окрема величина називається компонентом масиву. Тип компонентів може бути будь-яким, прийнятим у мові ПАСКАЛЬ, крім файлового типу. Тип компонентів називається базовим типом.
Уся сукупність компонентів визначається одним ім'ям. Для позначення окремих компонентів використовується конструкція, яку називають змінною з індексом чи з індексами:
A[5] S[k+1] B[3,5].
Як індекс може бути використане виразу. Тип індексів може бути тільки інтервальним чи типом, що перелічується. Дійсний і цілий типи неприпустимі. Індекси інтервального типу, для якого базовим є цілий тип, можуть приймати від’ємні, нульові і додатні значення.
В операторній частині програми один масив може бути привласнений іншому, якщо їхні типи ідентичні, наприклад:
R1:=Z.
Для вводу чи виводу масиву до списку вводу чи виводу вводять змінну з індексом, а оператори вводу чи виводу виконуються в циклі.
Перший індекс визначає номер рядка, другий - номер стовпця. Двовимірні масиви зберігаються в пам'яті ЕОМ по рядках.
Ініціалізація масивів (присвоєння початкових значень усім компонентам масивів) здійснюється двома способами.
· Перший спосіб - з використанням типізованих констант, наприклад:
type Dim10= Array[1..10] of Real;
const raM10: Dim10 = (0, 2.1, 4, 5.65, 6.1, 6.7, 7.2, 8, 8.7, 9.3);
При ініціалізації двовимірних масивів значення компонент кожного з вхідних у нього одномірних масивів записується в дужках:
type Dim3x2= Array[1..3,1..2] of Integer;
const iaM3x2: Dim3x2= ((1, 2)
(3, 4)
(5, 6));
· Другий спосіб ініціалізації - використання різновиду процедури FillChar:
FillChar(var V; NBytes: Word; B: Byte);
Ця процедура заповнює ділянку пам'яті однобайтовим значенням. Наприклад, для занулення масиву A[1..10] of Real можна записати: FillChar(A, 40, 0) чи FillChar(A, SizeOf(A), 0);
Рядки
Особливе місце в мові ПАСКАЛЬ займають масиви символів. Стандартний ПАСКАЛЬ допускає два способи збереження символьних масивів у пам'яті ЕОМ: розпакований і запакований. Розпаковані масиви символів зберігаються в пам'яті ЕОМ по одному символі в машинному слові, запаковані - по одному символі в байті. При описі запакованого масиву символів використовують службове слово PACKED, наприклад:
var MAS: Packed Array[1..20] of Char;
Опис розпакованого масиву символів має вид:
var M: Array[1..20] of char;
Для перетворення символьного масиву з розпакованої форми в запаковану і навпаки, з запакованої в розпаковану, у мові ПАСКАЛЬ введені дві стандартні функції Pack, UnPack.
Запакований масив символів утворить символьний рядок. Символьний рядок може бути або строковою константою, або строковою змінною. Рядкова константа, чи рядок, являє собою сукупність символів, укладену в апострофи. Рядок - це елементарна конструкція мови ПАСКАЛЬ. Рядкові константи можуть входити до складу виразів. Як і числові константи, вони можуть бути описані в розділі опису констант.
Рядкові змінні - це одномірні запаковані масиви символів, для опису яких у TURBO PASCAL уведений тип String.
Наприклад, якщо рядок містить до 30 символів, її тип буде визначений як
type s= String[30];
Довжина рядка не може містити більш, ніж 255 символів.
У TURBO PASCAL визначене поняття рядка змінної довжини, у цьому випадку його опис задається як
type s= String;
Тип String без указівки довжини може сполучатися з усіма типами рядків.
Особливістю строкових змінних є те, що до них можна звертатися як до скалярної змінної, так і до масиву. В другому випадку застосовується конструкція "змінна з індексом", що забезпечує доступ до окремих символів рядка. При цьому нижня границя індексу дорівнює 1. Окремий символ рядка може сполучатися з типом Char.
У пам'яті ЕОМ рядок займає кількість байтів, на одиницю більше її довжини. Нульовий байт рядка містить її довжину.
Для рядків визначені операції присвоювання, злиття (конкатенації) і порівняння.
Для порівняння рядків застосовуються всі операції відношень. Порівняння рядків відбувається посимвольно, починаючи з першого символу. Рядки рівні, якщо мають однакову довжину і посимвольно еквівалентні.
Рядки можуть бути елементами списку вводу - виводу, при цьому записується ім'я рядка без індексу.
При введенні рядковіх змінних кількість символів, що вводяться, може бути менше, ніж довжина рядка. У цьому випадку символи, що вводяться, розміщаються з початку рядка, а байти, що залишилися, заповнюються пробілами. Якщо кількість символів, що вводяться, перевищує довжину рядка, зайві символи відкидаються.
Ініціалізація рядків може здійснюватись як за допомогою типізованих констант:
const sName: String[9]= 'IBM PC/AT';
так і з використанням другого різновиду функції FillChar:
FillChar(var V; NBytes: Word; C: Char);
наприклад:
FillChar(A, SizeOf(A), '0');
Для роботи з рядками в TURBO PASCAL включені процедури і функції, що забезпечують редагування і перетворення рядків.
2.8 Обробляння рядків
Для обробки рядкових величин використовуються наступні вбудовані засоби:
· Оператор присвоювання: a:=”Volga”;
· Визначення кількості символів у рядку: k:=Length(Str); k- ціла змінна.
· Об'єднання рядків здійснюється двома способами:
1. Використання знака «+»:запис “ab”+”cd” дає значення “abcd”.
2. a:=Concat(Str1,Str2,…,StrN)...
· Перетворення числової величини x у рядкову s: Str(x,s), процедура використовується без знака присвоювання.
· Перетворення рядкової величини s у числову x: Val(s,x,code), процедура використовується без знака присвоювання. Змінна code – ціле число, що приймає значення, відмінне від 0, у випадку, коли вихідний рядок s не має вид числа і перетворення неможливе.
· Вирізка підрядка p довжиною n з рядка s, починаючи з k-го символу: p:=Copy(s,k,n);
· Визначення номера позиції початку підрядка p у рядку s: k:=Pos(s,p);. Якщо в результаті виходить k=0, то це значить, що підрядка в рядку не знайдений. Якщо в рядку мається декілька однакових шуканих підрядків то знаходиться тільки перша з них.
· Вставка підрядка p у рядок s, починаючи з позиції k: Insert(s,p,k);
· Видалення з рядка s, починаючи з p-го k символів: Delete(s,p,k);
2.9 Процедури і функції
Алгоритм рішення задачі проектується шляхом декомпозиції всієї задачі в окремі підзадачі. Зазвичай підзадачі реалізуються у виді підпрограм.
Підпрограма - це послідовність операторів, що визначені і записані тільки в одному місці програми, однак їх можна викликати для виконання з однієї чи декількох крапок програми. Кожна підпрограма визначається унікальним ім'ям. У мові ПАСКАЛЬ існують два типи підпрограм - процедури і функції.
Процедура і функція - це іменована послідовність описів і операторів. При використанні процедур чи функцій ПАСКАЛЬ - програма повинна містити текст процедури чи функції і звертання до процедури чи функції. Тексти процедур і функцій містяться в розділ описів процедур і функцій.
Процедура може містити такі ж розділи описів, що і ПАСКАЛЬ - програма, а саме: розділи опису модулів, міток, констант, типів, змінних, процедур і функцій.
У багатьох задачах, особливо в задачах обчислювальної математики, необхідно передавати імена процедур і функцій як параметри. Для цього в TURBO PASCAL уведений новий тип даних - процедурний чи функціональний, у залежності від того, що описується.
Опис процедурних і функціональних типів виробляється в розділі опису типів:
Type
FuncType = Function(z: Real): Real;
ProcType = Procedure (a,b: Real; var x,y: Real);
Функціональний і процедурний тип визначається як заголовок процедури і функції зі списком формальних параметрів, але без імені. Можна визначити функціональний чи процедурний тип без параметрів, наприклад:
Type
Proc = Procedure;
Після оголошення процедурного чи функціонального типу його можна використовувати для опису формальних параметрів - імен процедур і функцій.
Крім того, необхідно написати ті реальні процедури чи функції, імена яких будуть передаватися як фактичні параметри. Ці процедури і функції повинні компілюватися в режимі далекої адресації з ключем {$F+}.
Приклад. Скласти програму для обчислення визначеного інтеграла за методом Симпсона.
Обчислення підінтегральної функції реалізувати за допомогою функції, ім'я якої передається як параметр. Значення визначеного інтеграла за формулою Симпсона обчислюється за формулою:
ISimps=2*h/3*(0.5*F(A)+2*F(A+h)+F(A+2*h)+2*F(A+3*h)+...+2*F(B-h)+0.5*F(B)),
де A і B - нижня і верхня границі інтервалу інтегрування,
N - число розбивок інтервалу інтегрування,
h=(B-A)/N, причому N повинно бути парним.
Program INTEGRAL;
Type
Func= function(x: Real): Real;
Var
I,TN,TK:Real;
N:Integer;
{$F+}
Function Q(t: Real): Real;
Begin
Q:=2*t/Sqrt(1-Sin(2*t));
End;
{$F-}
Procedure Simps(F:Func; a,b:Real; N:Integer; var INT:Real);
Var
sum, h: Real;
J:Integer;
Begin
if Odd(N) then N:=N+1;
h:=(b-a)/N;
sum:=0.5*(F(a)+F(b));
for j:=1 to N-1 do
sum:=sum+(j mod 2+1)*F(a+j*h);
INT:=2*h*sum/3
End;
Begin
WriteLn(' ВВЕДІТЬ TN,TK,N');
Read(TN,TK,N);
Simps(Q,TN,TK,N,I);
WriteLn('I=',I:8:3)
End.
2.10 Модулі
Модуль (UNIT) у TURBO PASCAL - це особливим образом оформлена бібліотека підпрограм. Модуль на відміну від програми не може бути запущений на виконання самостійно, він може тільки брати участь у побудові програм і інших модулів.
Модулі дозволяють створювати особисті бібліотеки процедур і функцій і будувати програми практично будь-якого розміру.
Модуль у TURBO PASCAL являє собою окремо збережену і незалежно відкомпільовану програмну одиницю.
У загальному випадку модуль - це сукупність програмних ресурсів, призначених для використання іншими програмами. Під програмними ресурсами розуміються будь-які елементи мови TURBO PASCAL: константи, типи, змінні, підпрограми. Модуль сам по собі не є виконуючою програмою, його елементи використовуються іншими програмними одиницями.
Усі програмні елементи модуля можна розбити на дві частини:
· програмні елементи, призначені для використання іншими програмами чи модулями, такі елементи називають видимими поза модулем;
· програмні елементи, необхідні тільки для роботи самого модуля, їх називають невидимими чи схованими.
Відповідно до цього модуль, крім заголовка, містить дві основні частини, називані інтерфейсом і реалізацією.
У загальному випадку модуль має наступну структуру:
unit <ім'я модуля>; {заголовок модуля}
Interface
{ опис видимих програмних елементів модуля }
{ опис схованих програмних елементів модуля }
Begin
{ оператори ініціалізації елементів модуля }
End.
В окремому випадку модуль може не містити частини реалізації і частини ініціалізації, тоді структура модуля буде такою:
unit <ім'я модуля>; {заголовок модуля}
Interface
{ опис видимих програмних елементів модуля }
Implementation
End.
Використання в модулях процедур і функцій має свої особливості. Заголовок підпрограми містить усі зведення, необхідні для її виклику: ім'я, перелік і тип параметрів, тип результату для функцій, ця інформація повинна бути доступна для інших програм і модулів. З іншого боку, текст підпрограми, що реалізує її алгоритм, іншими програмами і модулями не може бути використаний. Тому заголовок процедур і функцій поміщають у інтерфейсну частину модуля, а текст - у частину реалізації.
Інтерфейсна частина модуля містить тільки видимі (доступні для інших програм і модулів) заголовки процедур і функцій (без службового слова forward). Повний текст процедури чи функції поміщають у частину реалізації, причому заголовок може не містити список формальних параметрів.
Вихідний текст модуля повинний бути відкомпільований за допомогою директиви Make підміню Compile і записаний на диск. Результатом компіляції модуля є файл із розширенням .TPU (Turbo Pascal Unit). Основне ім'я модуля береться з заголовка модуля.
Для підключення модуля до програми необхідно вказати його ім'я в розділі опису модулів, наприклад:
Uses CRT, Graph;
У тому випадку, якщо імена змінних у інтерфейсній частині модуля й у програмі, що використовує цей модуль, збігаються, звертання буде відбуватися до змінної, описаної в програмі. Для звертання до змінної, описаної в модулі, необхідно застосувати складене ім'я, що складається з імені модуля й імені змінною, розділеного крапкою.
Наприклад, нехай мається модуль, у якому описана змінна К:
Unit M;
Interface
var K: Integer;
Implementation
.................
End.
Нехай програма, що використовує цей модуль, також містить змінну К:
Program P;
Uses M;
var K: Char;
Begin
.............
End.
Для того, щоб у програмі P мати доступ до змінної K з модуля M, необхідно задати складене ім'я M.K.
Використання складених імен застосовується не тільки до імен змінних, а до всіх імен, описаних у інтерфейсній частині модуля.
Рекурсивне використання модулів заборонене.
Якщо в модулі мається розділ ініціалізації, то оператори з цього розділу будуть виконані перед початком виконання програми, у якій використовується цей модуль.
Множини
Поняття множини в мові ПАСКАЛЬ ґрунтується на математичному представленні про множини: - це обмежена сукупність різних елементів. Для побудови конкретного множинного типу використовується тип, що перелічується чи інтервальний тип даних. Тип елементів, що складають множину, називається базовим типом.
Множинний тип описується за допомогою службових слів Set of, наприклад:
type M= Set of B;
Тут М - множинний тип, В - базовий тип.
Приклад опису змінної множинного типу:
Type
M= Set of 'A'..'D';
Var
MS: M;
Приналежність змінних до множинного типу може бути визначена прямо в розділі опису змінних:
Var
C: Set of 0..7;
Константи множинного типу записуються у виді укладеної в квадратні дужки послідовності чи елементів інтервалів базового типу, розділених комами, наприклад:
['A', 'C'] [0, 2, 7] [3, 7, 11..14].
Константа виду [ ] означає порожню підмножину.
Множина містить у собі набір елементів базового типу, усі підмножини даної множини, а також порожня підмножину. Якщо базовий тип, на якому будується множина, має К елементів, то число підмножин, що входять у цю безліч, дорівнює 2 у ступені К. Нехай мається змінна Р интервального типу:
var P: 1..3;
Ця змінна може приймати три різних значення - або 1, або 2, або 3. Змінна Т множинного типу
var T: Set of 1..3;
може приймати вісім різних значень:
[ ] [1,2]
[1] [1,3]
[2] [2,3]
[3] [1,2,3]
Порядок перерахування елементів базового типу в константах може бути будь-яким.
Значення змінної множинного типу може бути задано конструкцією виду [T], де T - змінна базового типу.
До змінних і констант множинного типу застосовують операції присвоювання (:=), об'єднання (+), перетинання (*) і різниці (-):
['A','B'] + ['A','D'] дасть ['A','B','D']
['A'] * ['A','B','C'] дасть ['A']
['A','B','C'] - ['A','B'] дасть ['C'].
Результат виконання цих операцій є величина множинного типу.
До множинних величин можуть застосовуватись операції: тотожність (=), нерівність (<>), міститься в (<=), містить (>=). Результат виконання цих операцій має логічний тип, наприклад:
['A','B'] = ['A','C'] дасть FALSE
['A','B'] <> ['A','C'] дасть TRUE ['B'] <= ['B','C'] дасть TRUE ['C','D'] >= ['A'] дасть FALSE.
Крім цих операцій для роботи з величинами множинного типу в мові ПАСКАЛЬ використовується операція
in,
яка перевіряє приналежність елемента базового типу, що стоїть ліворуч від знака операції, множини, що стоїть праворуч від знака операції. Результат виконання цієї операції – булевський. Операція перевірки належності елемента множини часто використовується замість операцій відношення, наприклад:
A in ['A', 'B'] дасть TRUE,
2 in [1, 3, 6] дасть FALSE.
При використанні в програмах даних множинного типу виконання операцій відбувається над бітовими рядками даних. Кожному значенню множинного типу в пам'яті ЕОМ відповідає один двійковий розряд. Наприклад, множина
['A','B','C','D']
представлена в пам'яті ЕОМ бітовим рядком
1 1 1 1.
Підмножини цієї множини представлені рядками:
['A','B','D'] 1 1 0 1
['B','C'] 0 1 1 0
['D'] 0 0 0 1
Величини множинного типу не можуть бути елементами списку вводу - виводу.
У кожній конкретній реалізації транслятора з мови ПАСКАЛЬ кількість елементів базового типу, на якому будується множина, обмежена. У TURBO PASCAL кількість базових елементів не повинна перевищувати 256.
Ініціалізація величин множинного типу виробляється за допомогою типізованих констант:
const seLit: Set of 'A'..'D'= [];
Проілюструємо застосування даних множинного типу на прикладі. Приклад. Скласти програму, що виробляє і виводить на дисплей набори випадкових чисел для гри в "Спортлото 5 з 36". Для заповнення кожної картки спортлото необхідно одержати набір
з п'яти псевдовипадковихх чисел. До цих чисел пред'являються дві вимоги:
-числа повинні знаходитися в діапазоні 1..36;
-числа не повинні повторюватися.
Program Lotto;
Var
nb, k: Set of 1..36;
kol, l, i, n: Integer;
Begin
Randomize;
WriteLn('ВВЕДІТЬ kol');
ReadLn(kol); nb:=[1..36];
for i:=1 to kol do
Begin
k:=[];
for l:=1 to 5 do
Begin
Repeat
n:=Random(36)