вівторок, 2 червня 2020 р.

Користувацький тип даних Pascal




Крім стандартних типів даних Паскаль підтримує скалярні типи, визначені самим користувачем. До них відносяться перелічуваних типи (коли безпосередньо, в розділі опису типів, заздалегідь записуються всі значення для змінних цього типу) та інтервальні (коли задаються межі діапазону значень для даної змінної), вказівні тип (крім Pointer), структуровані типи і процедурні типи.

Дані цих типів займають в пам'яті один байт, тому скалярні призначені для користувача типи не можуть містити більше 256 елементів. Їх застосування значно покращує наочність програми, робить більш легким пошук помилок, економить пам'ять.
Тип-перелік
Тип-перелік даних задається безпосередньо перерахуванням всіх значень, які може приймати змінна даного типу. При описі окремі значення вказуються через кому, а весь список беруть в круглі дужки. наприклад,
Var    Season: (winter,spring,summer,autum );
       Temp: (23,24,25,26);

Інтервальний тип
Інтервальний тип дозволяє задавати дві константи, що визначають межі діапазону значень для кожної змінної.   Обидві константи повинні належати одному і тому ж стандартному типу (крім real). наприклад,
Var    S:1..30;
       Сh:'a'..'f';

Вказівний тип
Вказівні типи - їх значеннями є адреси пам'яті. На відміну від стандартного вказівного типу Pointer, призначений для користувача тип визначає безліч значень, які вказують на динамічні змінні певного типу, званого базовим типом. Покажчик на який-небудь тип може бути описаний до оголошення самого типу:
Type     PtStack=^Stack;
         Stack=array[1..40] of real;

Процедурний тип
Процедурний тип дозволяє оголошувати змінні, яким допускається присвоювання імен процедур, функцій і методів, а також передавати такі змінні і імена як параметрів. Опис процедурних типів має такий же синтаксис, як і оголошення процедур і функцій:
Type     Tproc1=procedure (var x,y:real);
         Tproc2=function ( x:real):real;

Cимвольний тип даних (CHAR)
Змінні порядкового типу Char використовуються для зберігання символів ASCII.
Символьні константи записуються в апострофах, наприклад:
'A', '3' або '*'
Один символ апострофа записується як два апострофа в апострофа, наприклад:
'' ''
Функція Chr перетворює значення Integer в символ з відповідним номером в таблиці ASCII.
Функція Ord повертає значення заданого символу ASCII.
Приклад: Відомо, скільки днів в кожному місяці року. Скільки днів влітку?
31,28,31,30,31,30,31,31,30,31,30,31
Один з варіантів вирішення даної задачі виглядає так:
const dni: array[1..12] of byte = (31,28,31,30,31,30,31,31,30,31,30,31);
var s,i: integer;
begin
s:=0;
for i:=6 to 8 do
    s:=s+dni[i]; {літні місяці - 6, 7, 8}
writeln(s)
end.
Код даного рішення має не найкращою наочністю, до того ж доводиться самому вираховувати номера місяців початку і кінця літа (6 і 8).
Зручність і наочність таких програм можна підвищити в такий спосіб:
TYPE    mes =   (january, february, march, april, may, june, july, august, september, october, november, december);
CONST   dni:array[january..december] of Byte =   (31,28,31,30,31,30,31,31,30,31,30,31);
VAR     s:Integer;
        i:mes; {змінна лічильника циклу i задана типом mes, а не Integer}
BEGIN
        s:=0;
        for i:=june to august do s:=s+dni[i];
        WriteLn(s)
END.
Приклад:
Поїзд відправляється в дорогу о 22 годині і знаходиться в дорозі 10 годин. У скільки він прибуває на місце призначення?
var otpravlenie,pribitie:0..24;
begin
otpravlenie:=22;
pribitie:=otpravlenie+10;
writeln(pribitie)
end.


Завдання для самостійного опрацювання

1. Type 2: Визначити за назвою дня тижня вихідний це чи робочий день.
Визначити перелічувальний тип зі значеннями днів тижня (mon, tue, wed, thu, fri, sat, sun).
Оголосити змінну, що відноситься до цього типу.
У програмі привласнити значення змінної (з значень типу, наприклад, mon).
Перевіряти змінну: якщо значення субота або неділя - видавати повідомлення «Вихідний!», Інакше «Працюємо!».
Реалізувати декількома способами.
2. Type 3: В залежності від місяця року, видавати повідомлення «холодно» - якщо зимовий місяць, і «тепло» - якщо річний.
Визначити перераховується тип зі значеннями назв місяців року.
Оголосити змінну, що відноситься до цього типу.
У програмі привласнити значення змінної (з значень типу).
Перевіряти змінну: якщо значення відноситься до зимового місяця, - видавати повідомлення «холодно» інакше, - «тепло».
Реалізувати декількома способамі.Type 3: В залежності від місяця року, видавати повідомлення «холодно» - якщо зимовий місяць, і «тепло» - якщо річний.
Визначити перераховується тип зі значеннями назв місяців року.
Оголосити змінну, що відноситься до цього типу.
У програмі привласнити значення змінної (з значень типу).
Перевіряти змінну: якщо значення відноситься до зимового місяця, - видавати повідомлення «холодно» інакше, - «тепло».
Реалізувати декількома способами.
3. Залежно від знака зодіаку видавати до якої стихії він відноситься:
Вогонь (Овен, Лев, Стрілець)
Повітря (Терези, Водолій, Близнюки)
Вода (Рак, Скорпіон, Риби)
Земля (Козеріг, Телець, Діва)
4. Type 5: Залежно від назви квітки, видавати до якого сезону року вона відноситься:
Весна: підсніжник, ірис, нарциси
Літо: ромашка, одуван, мак
Осінь: астра, хризантема, флокс
5. Приклад 2. Напишіть програму для виведення на екран всіх символів таблиця ASCII.
6. Приклад 3. Вивести в один рядок:
ABBCCC ... ZZ ... Z


В даному розділі розглянуто набір реалізацій А.Нікітін на мові Pascal стандартних алгоритмів, застосовуваних при вирішенні завдань олімпіадного програмування.


Числові типи даних в Pascal


Прості типи даних

Типи змінних, що набувають цілих значень, позначаються службовим словом Integer. Існують певні межі для значень величин цього типу:   -32768 .. 32767 .У пам'яті комп'ютера такі значення займають 2 байти. Спроба отримати значення, що виходить за межі діапазону, призводить до помилки транслятора.
У Паскалі існує можливість використання ще декількох різновидів цілих типів, які мають інші діапазони своїх значень.
Якщо вам наперед відомо, що деяка змінна може набувати досить невеликих значень протягом виконання алгоритму, то її можна описати типом Shortint тобто коротке ціле. У випадку, якщо вам навпаки потрібен дуже великий розбіг значень цілої змінної, можна скористатися типом Longint. Бувають такі програми, що працюють тільки з цілими додатними числами. І для такого випадку у Паскалі є відповідні типи - тип Byte та тип Word.
У таблиці 1 наведені прості типи даних Турбо Паскаль, обсяг пам'яті, який необхідний для зберігання однієї змінної зазначеного типу, множина допустимих значень і допустимі операції.
Таблиця 1 
Ідентифікатор
(тип)
Довжина (байт)
Діапазон значень
Операції
Цілі типи
integer
2
-32768..32767
+, -, /, *, Div, Mod, >=, <=, =, <>, <, >
byte
1
0..255
word
2
0..65535
shortint
1
-128..127
longint
4
-2147483648..2147483647
                                                         Дійсні типи
real
6
2,9x10-39 - 1,7x1038
+, -, /, *, >=, <=, =, <>, <, >
Цілі числа не можуть містити у собі дріб. Для від'ємного числа треба ставити знак мінус (-) перед значенням (числом). Не можна використовувати кому у введені такого числа, бо інакше буде викликана синтаксична помилка. Приклади цілих чисел:
  • 42
  • 10000
  • −233000
INTEGER (цілий)
 Об'єкти даних — учасники операцій — називаються операндами. Над операндами цілого типу можливі такі операції: + (додавання), - (віднімання), * (множення), DIV (цілочисельне ділення з відсіченням залишку), MOD (залишок від цілочисельного ділення). Ці операції виконуються точно. Порядок виконання звичайний: спочатку множення, ділення та отримання залишку, потім додавання та віднімання. Службові слова DIV і MOD з двох сторін повинні відокремлюватися пробілами.
 Приклади:
 5 div 2 = 2
5 mod 2 = 1
5 div 6 = 0
5 mod 6 = 5
Дійсні числа можуть містити у собі як цілі, так і дробові значення з точкою відокремлення від цілої частини. Для від'ємного числа треба ставити знак мінус (-) перед значенням (числом). Приклади дійсних чисел:
  • 20.0005
  • 99.9
  • −5000.12

REAL (дійсний)
 Дійсні сталі мають обов'язкову цілу частину, за якою записано дробову частину і порядок (cтепінь числа 10). Ціла частина – це непорожня послідовність цифр, дробова – непорожня послідовність цифр із крапкою на початку, а порядок – буква "E" або "e", можливо, із знаком "+" або "-", і однією або двома цифрами. Перед сталою може бути знак "-", і тоді вона задає від'ємне число: -12.345E-1.
 Абсолютна величина (модуль) дійсних чисел зазвичай знаходиться в діапазоні від 1Е-38 до 1Е+38. Якщо число по модулю менше, ніж 1Е-38, відбувається втрата значущості (перетворення на нуль), а якщо більше 1Е+38, то виникає помилка (переповнення). 
Розглянемо приклад
Число 1.2345 можна позначити багатьма різними способами, наприклад, 123.45´ 10-2. Тут воно має цілу частину 123, дробову частину .45 і десятковий порядок -2. Цьому запису відповідає стала мови Паскаль 123.45E-2, у якій 123 – ціла частина, .45 – дробова, а E-2 – порядок. Це ж число можна задати сталою 0.12345E1 або 0.012345E+2, або 1.2345, або 12345e-04. Подання числа сталою, у якій перед десятковою крапкою записано єдину цифру від 1 до 9, називається нормалізованим, наприклад, 9.81 або 1.0E2 (число 0 має нормалізоване подання 0.0).
Дійсні значення й операції, застосовні до них, утворюють тип дійсних з ім'ям real.
Як бачимо, цілі числа задаються як цілими сталими, так і дійсними, наприклад, 2 і 2.0. Проте їм відповідають два цілком різних подання того самого числа, тобто значення двох різних типів. І в машині вони обробляються по-різному.

Завдання для самостійного опрацювання

Задача 1 «Проста задача?»
Програма зчитує двозначне число і виводить через пропуск кожну цифру окремо.
Вхідні дані
Натуральне число з проміжку від 10 до 99 включно.
Вихідні дані
Два одноцифрових числа, розділених пропуском.

Задача 2 «Цифри»
Обчислити кількість цифр цілого невід'ємного числа n.
Вхідні дані
Одне невід’ємне  ціле число n (0 ≤ n ≤ 2 * 109).
Вихідні дані
Кількість цифр в числі n.
Задача 3* «Два кола»
Визначити кількість точок перетину двох кіл.
prb4
Вхідні дані
6 чисел x1, y1, r1, x2, y2, r2, де x1, y1, x2, y2 - координати центрів кіл, а r1, r2 - їх радіуси. Всі числа - дійсні, не перевищують по модулю 1000000000=109, задані не більше ніж з 3-ма знаками після коми.
Вихідні дані
Кількість точок перетину. Якщо точок перетину нескінченно багато, то вивести -1.
Задача 4** «Метелик-санітар»
Школярі, йдучи з дому до школи або навпаки - зі школи додому, люблять їсти цукерки. Але, як завжди, цю приємну справу іноді має неприємні наслідки – дітки. Мурзик завжди слідкував за чистотою шкільного двору і йому в цьому з радістю допомагали метелики, вдячні за чудові фотографії, зроблені ним. Метелики могли використовувати власні крильця як лінзи, причому вони могли змінювати їх фокусну відстань. Помітивши обгортку від цукерки, що лежала на шкільному подвір'ї в точці з координатами X1, Y1, метелик перелітав в точку з координатами X2, Y2, Z2, розташовану на шляху сонячних променів до обгортці і, змінюючи фокусну відстань своїх крилець-лінз, спалювали обгортку від цукерки .
Яку оптичну силу D мали крильця-лінзи метелика в цей момент?
Задача 5** «Пірати і монети»
n піратам вдалося справедливо розділити скарб із m золотих монет - кожен отримав свою частину відповідно до свого піратського рангу і стажу. Наймолодший пірат взяв a монет, а кожен наступний пірат брав на одну монету більше, ніж попередній його колега. Останнім був капітан, якому дісталося вдвічі більше від запланованого, очевидно, що після нього монет більше не залишилося.
Скільки було піратів разом з капітаном, якщо відомі a та m. Так як капітан без команди просто пірат, то n> 1.
Вхідні дані
Два натуральних числа a і m (1 ≤ a ≤ 100, m <15150). Вхідні дані коректні.
Вихідні дані
Кількість піратів n.


В даному розділі розглянуто набір реалізацій А.Нікітін на мові Pascal стандартних алгоритмів, застосовуваних при вирішенні завдань олімпіадного програмування.