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

Логічний тип даних boolean Pascal

Логічний тип( boolean) описує величину, що може бути лише хибною (false) або істиною (true), але на збереження якого відводять 1 байт.
Опис
    var  x, y, z: boolean;
Присвоєння значень
    X:= TRUE;   y:= 2>5;  z:= a=b;
Виведення
   writeln(y);
   Writeln(a>b);
Коли логічна змінна має значення TRUE, її внутрішнє представлення 1.
Коли логічна змінна має значення FALSE, її внутрішнє представлення 0.
Такі величини отримують, наприклад, у результаті обчислення логічних виразів з операціями порівняння (відношення). Для даних логічного типу визначено такі операції:
Таблиця істинності логічних операцій:
Значення
операндів
(аргументів)
Результат операції
X
Y
not X
and Y
or Y
xor X
false
false
true
false
false
false
false
true
true
false
true
true
true
false
false
false
true
true
true
true
false
true
true
false
Подамо приклад програми порівняння одного з трьох введених цілих чисел з сумою решти:

program example3;
var  a, b, c: integer;
    la,lb,lc: boolean;
begin
  write('Введіть 3 цілих числа через пропуск ');
  readln(a,b,c);
  la:=a>b+c;
 lb:=b>c+a;
 lc:=c>a+b;
  writeln('a>b+c b>c+a c>a+b');
  writeln(la:5,lb:6,lc:6);
end.
В останній вказівці після двокрапки вказано кількість позицій (символів) для виведення (останню заповнено). Результат роботи при введенні 3 4 5 буде таким.
Введіть 3 цілих числа через пропуск 3 4 5
a>b+c b>c+a c>a+b
False False False

Приклади

Програма
Пояснення
Результат роботи
 Const a=2; b=10;
 var x:boolean;
begin
  x:=a < b;
  Writeln(x);
end. 

a=2; b=10. Тому a < b вірна нерівність. Отже, x має значення TRUE, яке і виводиться на екран
TRUE
Const a=TRUE;    b=FALSE;
Begin
 writeln(b > a);
end. 
a=TRUE, тобто 1; b=FALSE, тобто 0. Тому b>a - невірна нерівність, тобто такий логічний вираз має значення FALSE
FALSE
 Const X=-2; y=2;
 Var Z:Boolean;
Begin
Z:=sqr(x)-sqr(y)=0; writeln(z);
end. 
X=-2; y=2. Тому sqr(x)-sqr(y)=0 - вірна рівність, тому Z має значення TRUE
TRUE
 Const F=7; D=5;
 Var Z:Boolean;
Begin
 Z:=1/F > 1/D;
 writeln(z);
end. 
F=7; D=5, F > D. Тому 1/F<1/D. Звідки 1/F > 1/D -невірно, тому Z має значення FALSE
FALSE



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

Задача Vinni.  Вінні Пух любить складати віршики говорячи речення задом наперед. Якось йому попалось довге складне речення і він забув свій віршик, пробуючи його виговорити. Складіть програму, яка б допомагала ведмедику легко складати такі віршики. Зауваження: віршик може складатись як із 1 слова, так і з декількох, розділених пропусками.

Технічні умови. Програма зчитує з клавіатури стрічку-віршик. В кінці віршика ніколи не ставиться крапка. Довжина віршика менша за 255 символів. Програма виводить на екран стрічку, яку отримано внаслідок повороту.

Приклад. Введення> роза.  Виведення> азор.
Приклад. Введення> Все медведи любят мед. Виведення> дем тябюл идевдем есВ

 
Задача Весела абетка. Петрик навчається в початковій школі. Він ще не дуже добре знає англійську абетку і тому дуже засмутився, коли Ольга Павлівна (учителька англійської мови) попросила його переставити літери слова S за абеткою (від «А» до «Z»). Допоможіть Петрику впоратися з завданням.
Вхідні дані: У рядку міститься слово S.
 Вихідні дані: У рядку міститься слово, яке утворилось під час перестановки літер.
 Обмеження: слово S містить від 1 до 10 символів, тільки маленькі латинські літери. Приклад вводу: champion Приклад виводу: Achimnop
Підказка: Очевидно, що слово, яке утворилося під час перестановки літер, містить стільки ж символів як початкове.

Тип даних рядки string Pascal


Рядки  
Рядок у загальному значенні цього слова — це скінченна послідовність символів. У мові Turbo Pascal значення-рядки записуються за допомогою апострофів, наприклад, 'ABC' або '12345'. Порожній рядок, тобто послідовність символів довжиною 0, позначається ' '.
        Для подання та обробки рядків мова Turbo Pascal надає спеціальний тип string [n] , де n— ціла константа (можливо, іменована) не більше 255. Значення типу string [ n ] — це по слідовності символів довжиною від 0 до n.
       Змінна типу string [ n ] являє собою масив символів з індексами від 0 до n. Нехай s — змінна типу string [n] . Елемент s [0] відіграє особливу роль. Значенням L = ord ( s [ 0 ]) може бути число від 0 до n — довжина рядка , що є значенням s . Сам рядок-значення представлено елементами з індексами від 1 до L .
 Елементи масиву-рядка з індексами від L + 1 до n невизна чені ; спроба їх використання може призвести до неочікуваних наслідків. їх значення варто розглядати як «сміття», що позна­ чено в наведених байтах знаком ?. Довжина рядка зберігається в одному байті й не переви­ щує 255 . Замість string [255] можна писати string .
Найпростішими виразами рядкового типу є ім'я змінної-рядка, рядкова константа (літерал) та вираз типу char . Для рядків означена двомісна операція конкатенації (об’єднання, дописування) . Результат утворюється шляхом дописування правого операнда до лівого: значенням '12' + '3' є '123 ' . Ціла довжина рядка повертається з виклику функції length із аргументом рядком: length (' 123 ') =3.
Рядковий вираз можна присвоїти рядковій змінній. Символи присвоюються елементам змінної, починаючи з першого. Довжина значення виразу стає довжиною значення змінної. Якщо ця довжина більша за максимально можливу довжину n змінної, то елементам змінної присвоюються n перших символів.

   Приклад. Нехай змінна s має тип string [3] . Після присвоювання s: = '12345' її послідовні елементи мають значення #3, '1', '2', '3' ; Після присвоювання s:='12' вони мають значення #2, '1', '2' , а елемент s [3] невизначений. Нехай за s = '12' виконуються оператори                 s: = s + '7' ; s : = '9' + s . Тоді s послідовно одержить значення '127' та '912 ' . Після s : = ' ' маємо: s [ 0 ] =#0 ,а всі інші елементи невизначені.
        Рядки, як і інші масиви, допускають використання та обробку їх окремих елементів, але тільки в межах значення ,поданого масивом. Наприклад, за s типу string [3] is ='12' можна присвоїти s [ 1 ] і s [ 2 ] символьні значення або використати їх, але s [3] є невизначеним. Можна також використовувати та змінювати s [ 0 ] . Наприклад, якщо за s = ' ' виконати s [ 0 ] : = chr (2) , то довжиною значення s стане 2 , тобто s [ 1 ] і s [ 2 ] будуть визначеними.     
Явне використання окремих елементів рядків, особливо елемента з індексом не рекомендується .
Для рядків означено операції порівняння =, <>, <, <=, >, >=. Рядки рівні , якщо мають однакову довжину і в її межах відповідні символи збігаються; інакше рядки не рівні.
        Рядки порівнюються відповідно до їх лексикографічного порядку , тобто як слова в словнику, тільки символами алфавіту є #0 , #1 , ..., #255 , упорядковані за номерами. Точніше, для не порожніх рядків s 1 < s 2 , якщо існує і , 1 ? і ? min { length (. j 7), length ( s 1)} , при якому sl [ i ] < s 2[ i ] , а всі відповідні елементи з індексами менше i у рядках рівні. У Pascal для визначення поточної довжини рядка служить функція lenght, Параметром даних функцій є рядок, значення довжини якого вони повертають. порожній рядок ' ' є найменшим.

УВЕДЕННЯ ТА ВИВЕДЕННЯ РЯДКІВ
Для введення-виведення рядків у мовах програмування, зазвичай, використовуються вбудовані підпрограми. Так у мові Pascal для цього служать стандартні процедури Read/ReadLn, Write/WriteLn.
       Уведення Якщо змінна має рядковий тип, a є файловою змінною типу text , то при виконанні read ) символи до найближчого кінця рядка або до кінця файла чи його ознаки #26 читаються та присвоюються елементам рядка ; доступним буде кінець рядка #13 (або кінець тексту #26 ). Сам символ #13 або #26 у рядок-змінну не записується. Якщо символів тексту до кінця рядка або тексту більше, ніж уміщається в , то заповнюється до кінця, і доступним стає перший символ після прочитаних у . Якщо перед читанням рядка за допомогою процедури read доступний кінець рядка, то він залишається доступним, а значенням стає порожній рядок.
Застосовувати read при введенні рядків небезпечно , особливо в циклі. Якщо після введення рядка доступним символом стане #13 , то подальші спроби читання рядків залишатимуть його доступним, і виконання програми може «зациклитися».
Приклад. Нехай змінні s 1 s 2 s 3 мають тип string [3] , а текст містить таку послідовність символів.
       Тоді після read ( f , sl , s 2, s 3) змінні мають такі значення: s1= ' 123 ', s2 = '45' ,  s3= ' ' ; доступним залишається символ #13 . Подальші спроби вводити з цього тексту в рядкові змінні будуть надавати їм значення ' ' й залишати доступним символ #13.
       Уведення рядків з клавіатури є аналогічним. Щоб виконання виклику read було закінчено, треба натиснути клавішу < Enter >.
Уведення рядків з клавіатури за допомогою процедури read не рекомендується , оскільки має додаткові «підводні камені».
       Виконання процедури readln аналогічно read, але після заповнення рядкової змінної або досягнення кінця рядка в тексті частина тексту разом із найближчим кінцем рядка пропускається й доступним стає перший символ наступного рядка. В умовах попереднього прикладу після виконання readln ( f , sl , s2, s 3) змінні матимуть такі самі значення, але доступним буде символ 'а' . Якби виконувалися виклики readln ( f , s1) ; readln ( f , s2) ; readln ( f , s3) , то s1 мало б значення '123 ', s2 — ' a ' , s3 — ' ' , а доступним став би символ #26 .
 Уведення рядків з текстових файлів та з клавіатури за процедурою readln надійніше, ніж за процедурою read . 
       Виведення. Виведення рядкових виразів не має особливостей — символи значення виразу виводяться в текстовий файл або на екран. Наприклад, якщо рядкова змінна має значення ' 12 ', то при виконанні виклику write ( s +'*'+ s ) виводяться символи 12*12.
       Приклад. 
Розглянемо програму, яка отримує рядки тексту від клавіатури та виводить у текстовий файл.
program CreateText;
var f:text; {файл-текст}
s:string; {рядок для введення з клавіатури) begin
writeln( 'Створення тексту.');
assign(f,'myfile . txt '); rewrite(f );
write ('Рядок і : ');
while not eof do begin
readln (s) ;
writeln (f , s) ;
writeln ('Рядок і : '); end;
close(f) end .
        Для закінчення роботи замість введення нового рядка треба натиснути < Ctrl + Z > і < Enter >. 
        Внаслідок особливостей системи Turbo Pascal довжина рядків, що набираються на клавіатурі, не більше 127 .
        Приклад. Розглянемо «копіювання» тексту за таких умов: рядки тексту мають довжину не більше 255 , а порожні рядки або ті, що містять лише пропуски, не копіюються.
        Власне «копіювання» опишемо процедурою; вхідний і цільовий файли-тексти задамо як її параметри. За умовою, рядки тексту «уміщуються» в змінних типу string , тому для введення тексту використаємо стандартну процедуру readln та змінну-рядок. Обробляючи рядок, визначимо, чи є в ньому хоча б один символ, відмінний від пропуску. Якщо є, рядок копіюється в цільовий текст.
program copyPress;
var f,g : text;
fName : string;
procedure copyNonEmpty(var f,g:text);
var s:string; {поточний рядок тексту}
k:byte; {лічильник позицій}
empty:boolean; {ознака порожності} begin
reset(f); rewrite(g);
while not eof (f) do begin
readln(f,s);
{обробка рядка s}
k:=l; empty:=true;
while (k<=length(s)) and empty do
if s[k] <> ' '
then begin
writeln(g,s);
empty:=false end else inc (k) ;
{рядок оброблено}
end;
close(f); close(g);
end;
begin
write('Вхідний текст: '); readln(fName); assign(f,fName);
write('Цільовий текст: '); readln(fName); assign(g,fName);
copyNonEmpty(f,g);
end.
        Для перевірки цієї програми достатньо вхідного тексту, в якому лише три рядки — порожній, складений кількома пропусками та рядок, що містить, крім пропусків, хоча б один інший символ. У цільовий текст має скопіюватися тільки останній рядок.
Завдання для самостійного опрацювання

Завдання 1. Вивести в один рядок: ABBCCC ... ZZ ... Z
Змінні:
i - змінна циклу; визначає, яка буква буде виводитися;
k - кількість повторень букви;
j - змінна циклу, лічильник кількості вже виведених букв.
Завдання 2. Скласти програму визначальну, яка з двох прізвищ довше. Прізвища мають різну довжину.
Завдання 3.  Дано два слова. Скласти програму визначальну вірно, що перше слово починається на ту ж букву, якої закінчується друге слово.
Задача 4. Обмін
У різдвяний вечір у віконці стояло три квіточки, зліва на право: герань, крокус та фіалка. Кожен ранок Маша витирала віконце і міняла містами стоявшу праворуч квіточку з центральною кввточкою. А Таня кожен вечір поливала квіточки і міняла місцями ліву та центральну квіточку. Потрібно визначити порядок квітів вночі після того, як пройде k днів.
Вхідні дані
Перший рядок містить кількість тестів m (1 ≤ m ≤ 12). В кожному з наступних m рядків знаходиться кількість днів k (k ≤ 1000).
Вихідні дані
Вивести m рядків, що містять по три латинських літери: "G", "C" и "V" (великі літери без пропусків), які описують порядок квітів на вікні по закінченню k днів (зліва направо). Позначення: G – герань, C – крокус, V – фіалка.
Приклад
Вхідні дані                2     1  5
Вихідні дані             VGC     CVG

завдання Vinni
Вінні Пух любить складати віршики говорячи речення задом наперед. Якось йому попалось довге складне речення і він забув свій віршик, пробуючи його виговорити. Складіть програму, яка б допомагала ведмедику легко складати такі віршики. Зауваження: віршик може складатись як із 1 слова, так і з декількох, розділених пропусками.
Технічні умови. Програма зчитує з клавіатури стрічку-віршик. В кінці віршика ніколи не ставиться крапка. Довжина віршика менша за 255 символів. Програма виводить на екран стрічку, яку отримано внаслідок повороту.
Приклад.
Введення> роза
Виведення> азор
Введення>  Все ведмеді люблять мед
Виведення>  дем тябюл ідевдем ЄСВ

Користувацький тип даних в 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.


Символьний тип даних
CHAR (символьний тип). Значенням символьної величини є один символ (літера, цифра і т.ін.). Всі символи занесено в спеціальну таблицю у певному порядку. Порядковий номер символу є кодом цього символу. Всього в таблиці 256 символів (порядкові номери від 0 до 255). Значення символьного типу записується у вигляді символу, взятого в одинарні лапки (апострофи). Для того, щоб представити сам апостроф, його потрібно повторити два рази.
 Приклади:
 ' А '
' Ь '
' 7 '
' ; '
' '' ' – так може бути представлений сам апостроф
 Коди великих та малих літер — різні. Оскільки символи мають порядкові номери (коди), то до них можна застосовувати лише операції порівняння одного з іншим. Наприклад, латинські літери розташовано в таблиці кодів в алфавітному порядку, тобто символ ' А ' має мінімальний код, a ' Z ' — максимальний (в ланцюжку великих латинських літер). Тому можна записати:
'А' < ' F '
'Y' > 'C'

'E' < > 'G'

Приклад: Відомо, скільки днів в кожному місяці року. Скільки днів влітку?
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