ПАСКАЛЬ: лексика, вирази, семантика.
Якщо хтось скаже, що йому потрібна мова програмування, в якій достатньо лише сказати, чого він хоче, щоб було зроблено – дайте йому льодяника.
А.Перліс, 1982 р.
1. Лексика мови Паскаль та загальний вигляд програми
2. Вирази з цілими та бульовими сталими
3. Вирази та оператори
4
. Семантика програми
1. Лексика мови Паскаль та загальний вигляд програми
Кожна мова починається з алфавіту
– скінченної множини символів. Алфавіт мови Паскаль складають:
великі й малі латинські букви A, B, ... , Z, a, b, ..., z;
десяткові цифри 0, 1, 2, ..., 9;
інші символи, серед яких + - * / = > < . , ; : ' ( ) [ ] { } ^ (у діалектах можливі й інші – вони тут не згадуються).
З символів алфавіту складаються лексичні
одиниці
мови – лексеми
, свого роду "цеглинки", подібні словам у природних мовах. Множина лексем мови і правил їх запису утворюють його лексику
. Лексеми неподільні й самі по собі позначають деякий зміст. Мова Паскаль має п'ять видів лексем: сталі, імена, знаки операцій, роздільники й коментарі.
Сталі
– це позначення чисел та інших елементів, представних у комп'ютері. Числові сталі (позначення чисел) мають вигляд, прийнятий у математиці, наприклад, 12, 3.1415926, 2.71828 тощо. Відзначимо лише, що цілу й дробову частини числа відокремлюють крапкою, а не комою. Числові й інші види сталих докладніше розглядаються далі.
Імена
– це послідовності букв і цифр, що починаються з букви
, наприклад, A, b52, x8z, jklmn. Великі й малі букви в іменах не різняться: Nam1, nAM1, nam1 суть те саме ім'я. Ім'я завжди позначає "щось"
, якийсь об'єкт, виділяючи його серед інших, тобто ідентифікуючи
. Тому імена ще називаються ідентифікаторами
.
Деякі імена використовуються спеціальним чином для утворення програми та її складових частин. Ці імена називаються зарезервованими
, або ключовими
, або службовими
словами
. Будемо записувати їх жирним
шрифтом
. Нам уже знайомі слова begin
, end
, program
. У додатку подано службові слова стандарту мови Паскаль – це звичайні англійські слова або їх скорочення. У діалектах їх більше.
Знаки
операцій
– це позначення операцій, виконання яких над числами й іншими значеннями породжує нові значення. Значення, до яких застосовується операція, називаються її операндами
, а породжуване значення – її результатом
. Вигляд знаків операцій дуже різноманітний. Нам звичний знак "+" і не зовсім звичні знаки "div
" і "<=", тобто імена й послідовності символів. Множину знаків операцій уточнимо далі.
До роздільників
відносяться дужки, символи ",", ";", ":", "(", ")" (тут їх узято в лапки) та деякі інші. Ними відокремлюються лексеми та інші, більш складні елементи програми.
У програмах можна записувати додаткові пояснення – коментарі
. Вони не задають ніяких дій, при трансляції пропускаються та призначені лише для того, щоб програму було легше зрозуміти. Коментар – це довільна послідовність символів, що починається символом "{", закінчується символом "}" і не містить "}" усередині. Припускається замість "{" записувати пару символів "(*", а замість "}" – пару "*)". Наприклад,
{ this is the comment (це коментар) } (* це теж *) { і це },
а це вже не коментар, а незрозуміло що}
.
Коментар можна записати між будь-якими двома лексемами, проте краще цим не зловживати, а записувати їх справа від тексту програми або в окремих рядках.
Суміжні імена й сталі відокремлюються пропусками – " ". Пропуск між сусідніми лексемами не обов'язковий, якщо хоча б одна з них є роздільником, коментарем або знаком операції (не ім'ям). Наприклад, знаки операцій + або - не є іменами, а знаки div
і mod
– є. Тому можна написати 1+2 або 1-2, але не можна 1mod
2 або 1div
2.
Програма, записана мовою Паскаль, має такий загальний вигляд:
program
ім'я
(input, output);
послідовність означень імен
begin
послідовність операторів
end
.
Перший рядок програми називається її заголовком
і містить ім'я програми (ідентифікатор). Інші рядки утворюють блок
програми
, що складається з означень імен (їх може і не бути) і тіла
begin
… end
. Крапка після останнього слова end
обов'язкова. Наприклад,
program
rrwl(input, output);
const
p=3.1415927;
var
r, lng : real;
begin
readln(r);
lng:=2*p*r;
writeln(lng)
end
.
У цій програмі з ім'ям rrwl є два означення. Перше означає ім'я p, яким далі позначається стала 3.1415927. Слово const
свідчить про те, що це означення саме сталої, а не чогось іншого. Друге означення означає імена r і lng двох змінних, про що свідчить слово var
(скорочення від англійського variable – змінна). Що таке сталі та змінні, ми дізнаємось у двох наступних підрозділах. У тілі програми записано три оператори, відокремлені символом ";". Перший з них задає читання з клавіатури дійсної сталої, що позначає радіус кола, другий – обчислення довжини цього кола та запам'ятання її в змінній lng, третій – друкування на екрані сталої, що позначає довжину кола.
2. Вирази з цілими та бульовими сталими
Цілі числа створив Господь Бог, решта є справою рук людських.
Л.Кронекер
2.1. Значення та сталі
У комп'ютер закладено способи подання чисел, символів і значень "істина" й "хибність". Ми розглянемо їх докладніше в розділі 7, а поки скажемо лише, що є два способи подання чисел – один для цілих і зовсім інший для дійсних. Далі будемо ототожнювати число та його подання в комп'ютері, хоч насправді це зовсім не те саме. Отже, в комп'ютері обробляються значення чотирьох видів – цілі й дійсні числа, символи та значення "істина" й "хибність", які називаються бульовими
. У мові Паскаль вони позначаються сталими. Тут ми розглянемо лише цілі й бульові сталі.
Ціла
стала
– це, як і в математиці, послідовність десяткових цифр, можливо, із знаком "+" або "-" попереду: 0, +1024, -273 тощо. У комп'ютері можна подати не всю множину цілих чисел, а деяку її скіненну підмножину, що залежить від комп'ютера й системи програмування. Найбільше з цілих чисел позначається ім'ям maxint. Однією з особливостей машинного подання чисел є те, що найбільше за модулем від'ємне число, представне в комп'ютері, можна задати виразом вигляду -maxint-1.
Бульові
сталі
мають вигляд false
і true
та позначають відповідно значення, про які ми звикли говорити "хибність" та "істина".
Отже, стала позначає значення
. Уживемо вперше загадкове слово "семантика
", що тлумачиться як "зміст": семантикою сталої є відповідне значення (число або щось інше). Взагалі, семантикою якогось позначення є те, що ним позначено
. У цьому розділі ми дістанемося й до поняття "семантики програми", тобто опишемо те, що вона задає.
2.2. Тип цілих чисел
Комп'ютер "уміє" виконувати операції з цілими числами. Знаки двомісних (бінарних) операцій +, -, * позначають додавання, віднімання та множення, наприклад, 2+3, 2-3, 2*3 (результатом чого будуть цілі 5, -1, 6). Знаками div
і mod
задається породження цілих частки й залишку від ділення цілих: результатом 7 div
2 є 3, а результатом 7 mod
2 – 1. Знак / також задає ділення, але результатом його є число в його "дійсному" поданні, тобто 4/2 – це не ціле, а "дійсне число 2" (докладніше про це в розд. 7). В усіх трьох діленнях дільник не може бути нулем – інакше результат не визначений. Знак "-" задає застосування одномісної (унарної) операції "мінус": -2, -(2+3).
Порівняння
цілих чисел задається знаками =, <>, >, <, >=, <= ("дорівнює", "не дорівнює", "більше", "менше", "не менше", "не більше"). Результатом є "істина" або "хибність": 1=2 – false
, 1<>2 – true
, 1>=1 – true
тощо. Операції порівняння називаються відношеннями
.
Є кілька операцій, що задаються дещо незвично, у вигляді f
(…), де f
– ім'я. Вирази такого вигляду називаються викликами
функцій
. Наприклад, вираз вигляду odd(x) задає обчислення ознаки непарності: значенням odd(7) є true
, odd(12) – false
.
До цілих чисел застосовні й інші операції (розд. 10).
Через скінченність множини цілих чисел, представних у комп'ютері, багато операцій із цілими визначені частково
. Так, не всякі два числа можна додати або умножити, оскільки результат може виявитися не представним у комп'ютері. Наприклад, maxint+1 або maxint*2.
Отже, ми визначили, хоча і не точно, множину "цілих чисел" Z
і множину операцій O
, застосовних до них. Пара
(МНОЖИНА ЕЛЕМЕНТІВ, МНОЖИНА ОПЕРАЦІЙ ІЗ НИМИ
)
у математиці називається типом
. Множина елементів називається носієм
типу
, а множина операцій – його сигнатурою
. Тип (Z
, O
) називається типом
цілих
і в мові Паскаль позначається ім'ям integer.
Тип цілих значень називається скалярним
, оскільки ці значення розглядаються як неподільні, тобто такі, що не складаються з окремих частин. Далі ми познайомимося з іншими скалярними типами мови Паскаль. Вони називаються базовими типами
цієї мови. Ми також познайомимося із структурними типами. Їх елементи, на відміну від скалярних, складені з частин, які можна позначати окремо.
Задача
2.1.
* Указати всюди і не всюди визначені операції над цілими. Відповідь обгрунтувати.
2.3. Булів тип
A
B |
A
and B |
A
or B |
not
A |
false false
|
false
|
false
|
true
|
false true
|
false
|
true
|
true
|
true false
|
false
|
true
|
false
|
true true
|
true
|
true
|
false
|
Сталі false
і true
позначають бульові значення "хибність" і "істина". До них застосовні операції "та", "або", "не", що називаються відповідно бульовим множенням (кон'юнкцією
), бульовим додаванням (диз'юнкцією
) і запереченням
. В мові Паскаль вони позначаються знаками and
, or
і not
. Результати застосування цих операцій до бульових значень подано в табл.2.1.
Крім бульових операцій, означено операцію "порядковий
номер
" ord: ord(false
)=0, ord(true
)=1. Порядковим номерам бульових значень відповідає результат їх порівняння: false
< true
. Очевидним чином означено й інші операції порівняння: =, <>, >, <=, >=.
У діалекті Турбо Паскаль додатково означено корисну операцію "виключне
або
", знак якої xor
:
false
xor
false
= true
xor
true
= false
,
false
xor
true
= true
xor
false
= true
.
Її ще називають "додавання за модулем 2
" – якщо подати false
і true
числовими значеннями 0 і 1 відповідно, а знак xor
замінити знаком Å , то
0 Å 0 = 1 Å 1 = 0, 0 Å 1 = 1 Å 0 = 1.
Отже, ми означили тип, що називається бульовим
і позначається ім'ям Boolean на честь видатного англійського математика й логіка Джорджа Буля, засновника математичної логіки.
Задачі
2.2.
*Виразити операцію xor
через інші бульові операції.
2.3.
* Указати значення, що утворюються в результаті застосування операцій:
а) (2*2=4) and true
; б) (2*2=4) or false
;
в) (not
true
) or false
; г) (ord(true
)=1) xor
(ord(false
)=0).
2.4. Вирази: процес обчислення та значення
Ціла або бульова стала є виразом
. Складніший вираз утворюється з простішого або простіших як
1. вираз у дужках;
2. два вирази й знак бінарної операції між ними;
3. вираз із знаком унарної операції перед ним;
4. виклик функції з виразом у дужках.
Ось приклади виразів: ((1)), true
and
false
, 1-(2+3), (1-2)+3, (1+2)<>3, -(5+3), odd(2), ord(odd(15)).
Те значення, до якого застосовується операція, називається її операндом
. Операнди позначаються виразами. Найпростішими з них є сталі. Вираз задає застосування операцій до операндів
– значень простіших виразів. Послідовність виконання цих операцій утворює процес обчислення значення виразу
.
Як бачимо, вираз має подвійний зміст, або семантику: З одного боку, він задає процес обчислення, а з іншого – він має значення. Наприклад, вираз 2*2=4 задає процес, у якому обчислюється добуток 2*2 і порівнюються два цілі значення 4 і 4, в результаті чого одержується значення true
.
Таким чином, на питання про те, що таке "2*2=5", математик відповів би, що це неправильна рівність, а програміст – що це позначення обчислень.
Результати операцій у процесі обчислення виразу запам'ятовуються для застосування до них подальших операцій. Останнє з обчислених значень також запам'ятовується для використання в програмі. Проміжні значення запам'ятовуються, як правило, в регістрах процесора, оскільки робота з ними відбувається набагато швидше, ніж робота з оперативною пам'яттю.
Як використовуються вирази? Їх значення можна іменувати, присвоювати змінним, виводити "у зовнішній світ" або використовувати для прийняття рішень про те
, що робити далі при виконанні програми. Всі ці незрозумілі слова ми почнемо пояснювати, починаючи з пункту 2.2.5.
Мова Паскаль в основному дотримується угод, що склалися в математиці про порядок застосування операцій у виразах. Це дозволяє не записувати зайві дужки, наприклад, усі розуміють, що 1-2*3 означає те ж саме, що і 1-(2*3). На порядок застосування операцій за відсутності дужок впливає їх старшинство
, або пріоритетність
. Якщо поруч із позначенням операнда записано знаки двох операцій, то спочатку виконується старша
з них, що має більш високий пріоритет. У табл.2.2 всі операції (не тільки над цілими) розбито на чотири групи, розташовані в порядку спадання пріоритету. Операції всередині кожної групи мають однакові пріоритети. Наприклад, вираз 1+(3+2)*2 задає, що після обчислення 3+2, тобто 5, воно множиться на 2, а не додається до 1.
Крім властивостей старшинства, операції мають властивості право
- або лівобічного
зв'язування
. У стандарті мови Паскаль усі двомісні операції мають властивість лівобічного зв'язування
: якщо ліворуч і праворуч від позначення операнда записано знаки операцій з однаковим старшинством, то спочатку застосовується записана ліворуч. Наприклад, 1-2*4+3 = (1-2*4)+3, але аж ніяк не 1-(2*4+3).
Застосування операцій, указаних у виразі, можна подати таким чином. Відшукаємо операцію, яка виконується першою, та від позначення її операндів проведемо стрілки вниз, і там запишемо результат. Потім зробимо те саме з операндами наступної операції, потім третьої тощо, поки не одержимо результат обчислення виразу. Приклади подано на рис.2.1.
Тип значення, обчислення якого задає вираз, називається типом виразу
.
У системі програмування Турбо Паскаль застосовується так зване "ледаче
", або скорочене
, обчислення
бульових операцій and
і or
. Спочатку обчислюється їх перший операнд. Якщо у випадку and
він є false
, то другий операнд не обчислюється, тому що результатом операції все рівно буде false
. Аналогічно якщо перший операнд операції or
є true
, то це й буде результатом, і другий операнд не обчислюється. Наприклад, вираз (2*2=5) and
(323345 div
17 = 0) задає обчислення лише 2*2=5, а (2*2=4) or
(323345 div
17 = 0) – лише 2*2=4.
Задачі
2.4.
* Обчислити значення виразу:
а) 2*ord(true
)+3*ord(false
); б) not true or false
; в) false
=true
=false
;
г) true
=false
=true
; д) 58 mod
13 div
10; е) 9 mod
5 * 12 div
16.
Подати його обчислення аналогічно рис.2.1.
2.5.
* Чи допустимий вираз:
а) 1=2=3; б) ord(true
) or
ord(false
);
в) 1=1 or
2=2; г) true
=false
and
true
=false
?
Якщо допустимий, то указати його значення.
2.5. Іменування виразів із сталими
Вираз із сталими, записаний у програмі, обчислюється не при виконанні програми, а в процесі трансляції. Значення такого виразу можна позначити ім'ям (іменувати
) і використовувати це ім'я далі в програмі. Іменування має вигляд
const
ім'я = вираз із сталими
;
(ключове слово const
означає "стала"). Іменування є означенням імені, яке після означення можна записувати в програмі замість виразу.
Корисно іменувати вираз, що записується в багатьох місцях програми, або "непостійно постійні", що можуть змінитися з часом уже після того, як створено програму, наприклад, деякі величини в економічних задачах. Якщо вираз іменований, то зміну потрібно внести лише в іменування, а якщо ні – доведеться змінювати вираз скрізь, де він зустрічається.
За словом const
можна записати кілька іменувань, відокремивши їх ";", причому у виразах можна використовувати імена вже іменованих виразів, наприклад:
con
a=12; b=2*a; tt=a+b;
Ім'я tt після цього позначатиме 24.
Саме з іменування виразів найчастіше починаються Паскаль-програми.
3. Вирази та оператори
3.1. Імена та змінні
Поняття змінної числової величини вперше з'явилося в роботах геніального француза Рене Декарта. Воно багато в чому визначило подальший розвиток математики. Пізніше, із створенням математичної логіки та теорії множин, виявилося, що змінна величина може бути не обов'язково числовою, а мати значеннями, наприклад, "істину" й "хибність" або множини елементів найрізноманітнішого походження. Так, можна говорити про змінну істинність фрази "тут зараз світить сонце" або про змінну множину команд Ліги чемпіонів з футболу.
У найзагальнішому значенні змінна
величина
– це узагальнення, абстракція якогось реального чи уявного об'єкта, або його окремої характеристики, що може перебувати в різних станах. Змінна звичайно позначається ім'ям, наприклад, у другому законі Ньютона a=F/m
у фізиці імена m, a, F
позначають змінні величини – масу тіла, прискорення його руху, та силу, що діє на нього. Як правило, змінна в міркуваннях ототожнюється з її ім'ям, і це не призводить до непорозумінь. Проте, ми майже завжди будемо відрізняти позначення від того, що ним позначено
.
У програмуванні змінна також є представником об'єкта, але "міркує" тепер комп'ютер, тому змінна
– це ділянка пам'ятіі, що своїми станами подає стани об'єкта
.
У програмах мови Паскаль (та інших мов високого рівня) змінні позначаються іменами, або ідентифікаторами. Імена можна вибирати будь-які, крім службових слів. Наприклад, ABRACADABRA, temperature, number, f1234qq тощо. У багатьох діалектах імена різняться тільки по перших восьми символах, наприклад, імена abcdefgh1 і abcdefgh2 невідрізнювані.
Змінна величина у математиці вважається заданою, якщо визначено множину значень, які вона може приймати. У Паскаль-програмі змінна задається означенням
, де записується її ім'я й тип:
var
ім'я
: ім'я
типу
;
наприклад,
var
temperature : integer;
або
var
even : boolean;
Ключове слово var
є скороченням англійського variable – змінна). Кілька однотипних змінних можна означити разом, указавши їх імена через кому:
var
a, b, c: integer;
Тип змінної задає множину її можливих значень, і операції, застосовні до них. Наприклад, цілі значення змінної temperature можна до чогось додавати або від чогось віднімати, а до значень змінної even можна застосовувати операцію заперечення, але не навпаки.
Кожна ділянка пам'яті має в комп'ютері щось на зразок номера – адресу
. Саме адресою вказується ділянка пам'яті в машинній програмі. Ім'я змінної, записане в Паскаль-програмі, в результаті трансляції перетворюється на адресу деякої ділянки пам'яті програми. При виконанні програми ця ділянка і є тією змінною, чиє ім'я записано в програмі
. Ми кажемо, що ім'я змінної вказує
, або посилається
на ділянку пам'яті під час виконання програми, або що ділянку поставлено у відповідність
імені (рис.2.2).
Проте поки незрозуміло, звідки в змінних беруться значення. Зараз дізнаємося.
3.2. Оператор присвоювання
Оператор присвоювання
має вигляд:
ім'я
змінної
:= вираз
(знак присвоювання ":=" – це лексема, яку не слід плутати зі знаком порівняння "="). Оператор присвоювання позначає:
1) обчислити значення виразу, записаного праворуч;
2) записати це значення в змінну, позначену ім'ям.
Отже, описані дії є семантикою оператора присвоювання
.
Приклад
. Якщо ім'я z означено як var
z : integer, то оператор присвоювання z:=11*(10+1) позначає обчислення значення 121 і запис його в змінну з ім'ям z. Після його виконання змінна з ім'ям z має значення 121.-
Пара вигляду (ім'я, значення) називається станом
змінної
, наприклад, (z,121) – стан змінної z після виконання оператора присвоювання. Таким чином, після присвоювання змінній нового значення її стан змінюється
.
Оператори присвоювання (і не тільки вони) в програмі записуються один за одним і відокремлюються роздільником ";", наприклад, z:=1; t:=2 (звичайно, за умови, що z і t означено як імена змінних типу integer). Оператори, записані один за одним, утворюють послідовність
операторів
. Кожен з них задає зміну стану хоча б однієї зі змінних.
Сукупність змінних, чиї імена означено в програмі, називається пам'яттю
програми
. Сукупність станів змінних називається станом
пам'яті
програми
. Зміна стану однієї зі змінних змінює стан пам'яті програми, тому оператор присвоювання задає зміну стану пам'яті програми
. Далі ми розглянемо інші види операторів, але
всі оператори задають зміну станів пам'яті програми
. Ця зміна і є їхньою семантикою.
Виконання операторів програми можна проімітувати
, указавши їх послідовність і послідовність станів пам'яті програми, що утворюються в результаті їх виконання. Якщо в процесі виконання програми змінна ще не одержала значення, то воно вважається невизначеним і позначається "?". Наприклад, ось програма та подання її імітації:
виконуваний оператор
|
стан пам'яті
|
||
x
|
y
|
z
|
|
? | ? | ? | |
z := 1 | ? | ? | 1 |
x := 3 | 3 | ? | 1 |
y := 15 | 3 | 15 | 1 |
x := 10 | 10 | 15 | 1 |
program
a2(input, output);
var
x, y, z : integer;
begin
z := 1;
x := 3;
y := 15;
x := 10
end
.
Звернімо увагу на те, що нові значення змінних записуються замість старих.
3.3. Вирази з іменами
Імена змінних, присвоювання значень яким задано в попередніх операторах програми, можна записувати у виразах. Значенням виразу, складеного лише ім'ям змінної, є значення цієї змінної, присвоєне їй раніш
. Наприклад, якщо змінна з ім'ям z має значення 2, то вираз z+1 задає додавання 2 і 1; значенням виразу буде 3. При іншому значенні z вираз z+1 мав би інше значення. Породження значення змінної за її ім'ям називається її розіменуванням
.
Приклад
. Послідовність операторів z:=2; z:=z+1 задає присвоювання змінній z спочатку 2, а потім обчислення 2+1 і присвоювання 3 цій же змінній. Сам по собі оператор z:=z+1 задає збільшення значення змінної з ім'ям z на 1, яким би це значення не було (аби воно було присвоєно).-
Отже, ім'я змінної у виразі задає її значення в момент обчислення виразу
. Тому ми кажемо, що вираз обчислюється при поточних значеннях вказаних у ньому змінних, або на поточному стані пам'яті
. Наприклад, послідовності операторів x:=2; z:=x+1 і x:=5; z:=x+1 задають присвоювання різних значень (3 і 6) змінній z у результаті виконання того самого оператора z:=x+1.
Крім імен змінних, у виразах можна записувати іменовані сталі. Вони також розіменовуються, наприклад, якщо означено const
cc=169, то вираз cc-25 має значення 144. Зазначимо, що він обчислюється в процесі трансляції програми.
Задачі
2.6.
* Нехай a, b, c, ... – імена цілих змінних. Написати арифметичний вираз, значенням якого є:
а) більше з двох значень a і b;
б) значення останньої цифри в десятковому поданні a, наприклад, при a=789 це 9;
в) сума значень цифр двозначного a, наприклад, при a=83 це 11;
г) сума значень цифр тризначного a, наприклад, при a=123 це 6.
2.7.
* Нехай a, b, c, … – імена цілих змінних із додатними значеннями. Написати булів вираз, значенням якого є true
тоді й тільки тоді, коли:
а) a, b, c мають однакові значення;
б) a, b, c задають сторони трикутника;
в) a, b, c задають сторони прямокутного трикутника;
г) a, b, c задають сторони гострокутного трикутника;
д) a, b, c задають сторони равнобедреного трикутника;
е) a, b, c задають сторони різнобічного трикутника;
ж) a, b, c, d задають сторони паралелограмма;
з) a1, b1, c1 і a2, b2, c2 задають сторони двох рівних трикутників;
и) цеглину a´ b´ c можна просунути в прямокутне вікно d´ e так, що її грані паралельні сторонам вікна.
2.8.
Написати вираз, значенням якого є true
тоді й тільки тоді, коли дві прямі, задані цілими коефіцієнтами рівнянь вигляду ax
+by
+c
=0:
а)* паралельні й не збігаються; б) паралельні (можливо, збігаються);
в) збігаються; г) перетинаються; д) перпендикулярні.
2.9.
* Підлога в кімнаті складається з клітин і має розміри n
´ m
. На двох клітинах поставлено стовпи. Написати вираз, яким задається ознака того, що тепер підлогу можна покрити дощечками розмірами 2´ 1.
2.10.
*Написати послідовність операторів, що задає обмін значень двох змінних за умови:
а) можна використовувати третю змінну;
б) третю змінну не використовувати, але змінні числові.
2.11.
Написати послідовність операторів для "циклічного" обміну значень трьох змінних (a¬ b, b¬ c, c¬ a).
2.12.
Нехай x – числова змінна. Використовуючи лише операції множення та оператори присвоювання змінним із будь-якими іменами, написати послідовність операторів для обчислення значення:
а)* x10
; б)* x12
; в) x15
; г) x31
.
Бажана послідовність із мінімальним числом множень. Наприклад, обчислення x6
можна задати так: x2:=x*x; x4:=x2*x2; x6:=x4*x2.
3.4. Обчисли й напиши
Комп'ютер виведе значення виразу на екран, якщо написати цей вираз в "операторі
" запису
, або виведення
:
writeln(вираз
)
Насправді цей "оператор" є викликом
спеціальної програми, що називається "процедура запису writeln" (від англійського write line – "записати рядок"). При її виконанні комп'ютер обчислює значення виразу, за цим значенням створює відповідну сталу, тобто послідовність символів, і передає її пристрою, частиною якого є екран. І вже в цьому пристрої стала друкується на екрані. Наприклад, при виконанні операторів програми з цілою змінною z
z:=1; writeln(1+z);
writeln(z<=1)
на екрані з'являються символи:
2
true
На екрані майже завжди присутня світлова позначка – курсор
. При виконанні "оператора" запису стала виводиться, починаючи з того місця на екрані, де знаходиться курсор. Після виведення курсор пересувається в наступний рядок екрана.
Усередині дужок "оператора" writeln можна написати кілька виразів через кому. Вони обчислюються один за одним і сталі, що подають їх значення, виводяться підряд, а курсор пересувається в наступний рядок після виведення останньої сталої. Наприклад, у результаті виконання операторів
x:=2; writeln(1,x, x*x, x*x>2)
на екрані з'явиться 124true
.
У "операторах" виведення нарівні з виразами можна записувати послідовності символів у апострофах, наприклад, 'x=', '123' тощо. Вони називаються рядковими
сталими
, або літералами
, і виводяться так само, як записані в програмі, тільки без апострофів. Наприклад, за операторами
x:=2; writeln( 1, ') x=', x, '; x2=', x*x, '; x2>2 : ', x*x>2 )
на екран виводиться
1) x=2; x2=4; x2>2 : true
.
За виразом у "операторі" виведення можна написати двокрапку і за ним цілу сталу, наприклад, x+y:10. Стала задає так звану ширину
поля
, у яке виводяться символи значення виразу. Якщо кількість символів менше, ніж ця ширина, то спочатку виводяться пропуски (доповнюючи символи до ширини поля), а якщо символів більше, то виводяться всі вони. Наприклад, при виконанні операторів
x:=10; writeln('x=', x:5, ', x2=', x*x:1)
на екран перед 10 виводиться три пропуски, а також усі цифри 100:
x= 10, x2=100
Ще один "оператор" виведення, а точніше, процедура write ("записати"), відрізняється від процедури writeln лише тим, що при її виконанні після виведення останньої сталої курсор не пересувається в наступний рядок екрана. Наприклад, при виконанні операторів
x:=2;
write('x=', x);
write(', x2>2 : ', x*x>2)
на екран виводиться
x=2, x2>2 : true
і курсор залишається праворуч від останньої букви "e".-
За допомогою "операторів" writeln і write можна задавати виведення не лише на екран, але й на інші носії даних, наприклад, у файли на диску. Але про це у розділах 13 і 14.
Задача
2.13.
Написати програму виведення на екран числа 16, його квадрата 256 і куба 4096 в одному рядку через два пропуски. Сталих 256 і 4096 явно не використовувати.
3.5. Читання, або присвоювання "із зовнішнього світу"
Оператор присвоювання – не єдиний спосіб, у який задається присвоювання значень змінним. Змінна може одержати значення "із зовнішнього світу" при виконанні "оператора
" читання
, або введення
, що у найпростішому випадку має вигляд readln( им'я-змінної
). Насправді це виклик спеціальної програми, що називається "процедура читання readln" (від англійського read line – прочитати рядок).
При виконанні "оператора" читання
readln ( им'я-змінної
)
комп'ютер зупиняється й чекає, що на клавіатурі буде набрано сталу того ж типу, що й тип указаної змінної. У відповідь слід набрати якусь сталу на клавіатурі (вона відображається на екрані). Але нічого не відбудеться, якщо після цього не натиснути на клавішу "Enter". Тільки після "Enter" цю сталу, тобто послідовність символів, буде передано від клавіатури в комп'ютер, а він за цією сталою обчислить відповідне значення та присвоїть змінній.
Якщо натиснути "Enter", не набравши сталу, то комп'ютер продовжить своє чекання. Перед числовою або бульовою сталою можна набрати також довільне число пропусків.
Якщо замість сталої набрати щось інше, наприклад, сталу іншого типу, то виконання програми на цьому завершиться (аварійно), і на екрані з'являться образливі слова про те, що вхідні символи були неправильними. Наприклад, якщо при виконанні оператора readln(z), де ім'я z позначає цілу змінну, набрати 1024
і натиснути "Enter", то значенням z стане 1024, а якщо набрати z=1024
, то програма аварийно завершиться, тому що ціла стала не може починатися символами "z=".
У "операторі" введення можна написати кілька імен змінних, відокремивши їх комами. При його виконанні треба набрати відповідну кількість сталих, відокремивши їх пропусками або натисканнями на клавішу "Enter" у довільній кількості. І поки всі сталі не будуть набрані, виконання такого "оператора" не закінчується.
Приклад
. Нехай x : integer, y : boolean. При виконанні readln(x,y) слід набрати цілу сталу, потім додати хоча б один пропуск або натискання на "Enter", а потім натиснути на клавіші t,
r
, u
, e
або f
, a
, l
, s
, e
, тобто набрати бульову сталу true
або false
. І не забути натиснути на "Enter" наприкінці.-
І ще одне зауваження з приводу використання readln. Практично перед кожним "оператором" читання з клавіатури не завадить написати "оператор" запису з запрошенням до введення значень і поясненням, яких саме типів і в якій кількості
. Наприклад, якщо x1
, x2
означено як цілі:
writeln('введіть два цілих числа');
readln(x1, x2).
Без такого запрошення невідомо, що робити тому, хто запустив програму на виконання, і чи виконується вона взагалі. Не уподібнюйте свої програми мовчазним привідам.
Операторами readln задається читання не лише з клавіатури, але також і з інших зовнішніх носіїв, наприклад, файлів на диску. Але про це у розділі 13.
Задача
2.14.
Написати програму читання двох чисел a
й b
та:
а)* друкування їх суми; б) друкування, чи вірно, що a<b
3.6. Ініціалізація змінних
Крім операторів присвоювання та читання, є ще один спосіб присвоїти змінній значення – безпосередньо в її означенні. Означення змінної з присвоюванням називається ініціалізацією
. Природним її виглядом був би такий:
var
ім'я
: тип
:= вираз
зі
сталими
;
наприклад, var
bool : boolean := true
; kb8 : integer := 1024*8;
Проте у системі Турбо Паскаль ініціалізація має інший вигляд. Досить дивний. Означення змінної починається словом const
і замість знака присвоювання записується знак "=":
const
bool : boolean = true
; kb8 : integer = 1024*8;
Вираз, що ініціалізує змінну, обчислюється під час трансляції
програми, тому може містити сталі й іменовані сталі, означені вище в програмі. Але імена змінних (у тому числі ініціалізованих) у ньому заборонені
. Таким чином, можлива послідовність означень
const
kb1=1024; kb8:integer=8*kb1;
але неможлива
const
kb1:integer=1024; kb8:integer=8*kb1; {???
}
3.7. Семантика програми
Підіб'ємо підсумок цього розділу. Паскаль-програма складається з двох основних частин – означень імен та тіла, яке є послідовністю операторів. Ми познайомилися поки що з означеннями імен лише сталих і змінних.
При виконанні програми сталим та їх іменам ставляться у відповідність значення базових типів, представні в комп'ютері. Іменам змінних ставляться у відповідність ділянки пам'яті
. Сукупність цих ділянок пам'яті утворює пам'ять процесу виконання програми
, яка часто не зовсім точно називається пам'яттю програми.
В операторах програми записуються вирази, що задають обчислення значень
. При виконанні операторів ці значення записуються в ділянки пам'яті, поставлені у відповідність іменам змінних (присвоюються їм) або використовуються з іншою метою. З цим ми познайомимося в наступних розділах. Присвоювання значення змінній означає зміну її стану. Тим самим змінюється стан пам'яті процесу виконання програми. Отже, оператори присвоювання та інші задають зміну станів пам'яті
.
Послідовність дій, заданих операторами та виразами у них, утворює процес виконання програми
. У процесі розв'язання більшості реальних задач доводиться приймати рішення та продовжувати процес розв'язання одним із кількох різних можливих шляхів. В наступних розділах ми познайомимося з засобами, за допомогою яких програма задає не єдиний можливий процес її виконання, а деяку їх множину. Саме ця множина процесів виконання програми і є її семантикою
. Так само семантикою алгоритму є множина процесів його виконання.