Розгалуження в програмі
Наступний ранок був повною протилежністю до попереднього. Вранішнє сонце вставало неначе вмитим, майже прозорим, і ніби кожним промінчиком, якось по-дитячому несміливо, просило вибачення за вчорашній часто похмурий, часто сльозливий день. А ось роси було стільки, що ні пройти, ні проїхати. Трави аж вгнулися, кожна високоросла рослинка стогнала під масою води, а кожне дерево стало душовою установкою. На те, що зранку допустять до комп’ютера, годі було й сподіватися. Маркіз за таких обставин надумав продовжити займатися математичною підготовкою Барсика, але Барсик проявив іншу ініціативу:
- Коли ми займемося вдосконаленням моєї програми відгадування чисел? — було перше, що він, навіть не привітавшись, запитав, зустрівши Маркіза.
- Не так скоро, як тобі хотілося б, — відповів Маркіз і, бачачи нерозуміння в очах товариша, спробував пояснити свою позицію. — Для цього необхідно, щоб ти уяснив, що таке умовний оператор, або команда розгалуження...
- Це те, про що ви вчора говорили з дядьком Миколою? — пригадав Барсик і вже зацікавлено додав: — Що ж тут такого особливого? Чому оператор умовний, чи він не дійсний, не існуючий?
- Чому ж? — Маркіз був явно не готовий до уроку, але продовжив: — Він дійсно існує, а працює цей оператор з огляду на умову. Особливим є те, що залежно від умови цей оператор сам вибирає, яку команду в подальшому виконувати. Якщо умова виконується, то виконується одна послідовність команд, якщо ж умова не виконується, то виконується інша послідовність команд. Щось зрозумів? Наприклад, пригадай учорашній і попередні дні. Залежно від погоди ми працювали на комп’ютері або були надворі. Для складання
планів нашої роботи на майбутнє нам потрібно враховувати погодний фактор, а в планах записати таке складнопідрядне речення: «Якщо буде дощ, то розв’язуємо задачі, інакше — вчимося на комп’ютері». Ось таку форму має умовний оператор: «Якщо умова, то дія 1, інакше — дія 2».
Тут несподівано Маркізові спав на думку, як він вважав, вдалий приклад: — Ти пам’ятаєш перемикач води у ванні? Якщо ручечку перемикача повернути вліво, то вода побіжить по гусачку в саму ванну...
- А якщо вправо, — не дав йому закінчити Барсик, — то по стояку на душову лійку. Так ти хотів сказати? Але ж тут керує потоком води не програма, а користувач...
- Я хотів сказати, що вода потече в тому чи іншому напрямку залежно від положення перемикача, — уточнив Маркіз.
- Отже, в цьому прикладі умову встановлює перемикач? — забубонів Барсик. — Якщо перемикач уліво, то потече вниз, а якщо вправо — то вгору. До чого ж тоді «інакше»?
- Перемикач має два положення: вліво і вправо, — спробував прояснити ситуацію Маркіз, — тоді немає потреби вдруге формулювати протилежну умову і можна сказати: «Якщо перемикач вліво, то потече вниз, інакше — вгору». Тут слово «інакше» заперечує умову «перемикач вліво», а якщо не вліво — то куди? Звичайно, вправо.
- Давай краще, на числах, мовою Паскаль, а то я щось не дуже... — попросив Барсик.
- Паскаль — то Паскаль, — погодився Маркіз. — І мені так легше буде. Так ось, нехай змінна х дійсного типу набуває значень на проміжку від —1000 до 1000, а змінна у залежить від значення х і дорівнює абсолютній величині змінної х або, як кажуть у математиці, модулю х. Пам’ятаєш? Ми не так давно говорили про це. Завдяки умовному оператору мовою Паскаль це запишеться так: If х>=0 then у:=х else у :=-х;, тобто у формі: If умова then команда 1 else команда2;
Барсик довго вдивлявся у цей запис, врешті запитав: «Можна, я запишу так (див. табл.)
if |
x>=0 |
then |
у:=х |
else |
у:=-х |
Якщо |
X неві д’ємне |
то |
У присво їти значення X |
інак ше |
у присвоїти значення протилежне X |
- Так ти зрозумів, що я хотів пояснити стосовно умовного оператора, — зрадів Маркіз. — А якщо умову х > 0 змінити на протилежну, як ти запишеш умовний оператор? — Маркіз хитрувато примружився.
- Можливо, так, — неспішно почав Барсик, — If х<0 then у:=-х else у:=х;
- Знаєш, з тебе можуть вийти люди, якщо до осені мухи не заклюють, — пожартував Маркіз.
- Ти неправильно побудував фразу, — підтримав жарт товариша Барсик. — Потрібно було сказати так: «Якщо мухи не заклюють, то можуть вийти люди...». Стривай. А де ж «інакше»? Щось тут не те, чи чогось не вистачає.
- А ти, виявляється, уважний. Молодець, — похвалив свого підопічного Маркіз. — Справа в тому, що в моєму прикладі умовний оператор записано у так званій повній формі, а є ще скорочена. Розглянемо задачу: визначити відстань х від точки числової прямої, заданої її координатою х, до початку відліку. Наприклад, точку числової
прямої, що лежить праворуч від початку координат на відстані 5 одиничних відрізків, позначили буквою А, тобто А(5). Пригадав? Нарисуй пряму. Познач початок. Як його позначити? Ну, звичайно, підпишемо, як на лінійці, знизу 0. Відклади вправо п’ять однакових відрізків. Кінець останнього познач зверху буквою А, а знизу підпиши число 5. А тепер відклади вліво від початку три таких, як відкладав вправо, маленьких відрізки. Саму ліву поділку познач зверху буквою В. Яке число підпишеш під нею?
Барсик мовчки написав число -3 і поглянув на товариша.
- Молодець, — знову похвалив його Маркіз. — Наука в ліс не йде... І пам’ять хороша. Так ось, згідно з умовою задачі, якщо координата х = 5 , то відстань х = 5 ; якщо координата х = -3 , то відстань х = 3, тобто д; = -(-3) = 3. Мовою Паскаль я записав би це так: If х<0 then х:=-х; Це і є скорочена форма умовного оператора If умова then команда;. Тепер же запиши програми розв’язування обох задач, а я збігаю, подивлюся, що там у нас на сніданок.
Коли Маркіз повернувся, на піску красувалася таблиця:
Повна форма умовного оператора |
Скорочена форма умовного оператора |
Program Прикладі; var х,у: Real; begin write('Введіть число'); read(х); if х<0 then у:=-х else у:=х; write('Модуль цього числа',у); end. |
Program Приклад2; var х: Real; begin write('Введіть координату'); read (х); if х<0 then х:=-х; write('Відстань до початку',х); end. |
Після сніданку, так і не дочекавшись запрошення до хати, друзі, хоча й ситі, проте розчаровані, повернулися до свого класу під відкритим небом, як охрестив Барсик купу піску.
- Що ми тепер будемо робити? — розпхинь- кався Барсик.
- Те, що й учора. Розв’язувати задачі, писати програми, — відповів Маркіз, не знаючи чим зацікавити малого. Йти до комп’ютера — мало напра- цювань, розв’язувати задачі — не завжди цікаво.
- Ти знаєш, що кожне парне число ділиться на 2 без остачі? — це питання, бадьорий голос Маркіза змусили Барсика перемкнути свої безнадійні думки на робочий режим.
- Парні — це 2, 4, 6, 8, 10...? — все ще в’яло перепитав він.
- Парні — це ті, що діляться на 2 без остачі,
- повторив Маркіз. — Парні — це ті, що кратні 2, парні — це ті, що ти назвав, і ще безліч тих, що закінчуються парною цифрою.
- І що з того? — чекаючи чогось несподіваного чи якихось підводних рифів, Барсик зосередився.
- Чого наїжачився? — покепкував з нього Маркіз. — Давай напишемо програму, яка вказувала б, парне введене з клавіатури число чи непарне, а заодно познайомишся з процедурою знаходження остачі від ділення одного цілого числа на друге, теж ціле число. Отже...
Та Барсик раптом жваво встряв у розмову:
- Отже, названі мною числа «парні», а ті, які я пропустив — «дєвкі»? Так, чи що?
Маркіз пропустив мимо вух «випад» малого і продовжив:
- Операцію визначення остачі від ділення двох натуральних а і Ь чисел мовою Паскаль записують так: а mod b. Наприклад: 5 mod 2 = 1; 12 mod 5 = 2; 4 mod 2 = 0; 25 mod 5 = 0; 100 mod 10 = 0...
- Якщо я зрозумів правильно, — вихопився Барсик, — то парні числа при діленні на 2 дадуть в остачі нуль. Точно! Непарні числа при діленні на 2... Стривай... Остача не може бути нулем... не може бути більшою за 2... Остача буде 1. Все правильно. Слухай: якщо число парне, то остача від ділення на 2 буде нуль, якщо ж непарне, то 1.
- Ось ти й сформулював ключову фразу, — втрутився Маркіз. — Якщо a mod 2 = 0, то а парне, інакше а непарне. Пиши програму, тільки пам’ятай, що операція «остача від ділення» виконувана на множині натуральних чисел, тобто цілих додатних.
Барсика не потрібно було довго вмовляти, і через кілька хвилин з’явився текст:
Program ПрикладЗ;
var a: Integer;
begin
write('Введіть натуральне число ');
read(а) ;
if (a mod 2)=0 then write(a,'- парне.')
else write(а,'-непарне.') ;
end.
- Оціни! — Барсик, явно задоволений, звернувся до Маркіза.
- Ця програма має шанс на життя, — запевнив його Маркіз. — А тепер склади програму, яка визначала б більше із двох введених дійсних чисел.
- Легко! — запевнив Барсик і, не знаючи які підводні камені чатують на нього, написав:
Program Прикладі; var a,b: Real;
begin
write('Введіть два числа ');
read(а,b);
if a>b then write(а:5:2, ' більше ‘ b:5:2)
else write(b:5:2,' більше ',а:5:2);
end.
- Ця програма буде непогано працювати, але якщо користувач введе два рівних числа, то вона
виведе повідомлення про те, що друге число більше за перше. Ти зрозумів? — Маркіз підсунув перший камінчик. — Ввели рівні числа, а програма пише, що одне з них більше за друге. Ти ввів дві п’ятірки, а на екрані написано: «5 більше 5».
- Але ж я думав правильно, — знітився Барсик, — і писав правильно. Що ти видумуєш?
- Правильно для випадку, коли числа різні, а ми говоримо про випадок, коли числа рівні, — стояв на своєму Маркіз, але, бачачи нерозуміння в очах Барсика, вкотре пожалів малого, — між двома числами можуть бути не два, як у програмі, а три види відношень: числа рівні; перше введене більше, ніж друге; перше менше, ніж друге. У твоїх позначеннях це запишеться так: а = b, або а>b , або а<b.
- Тоді я напишу: «Введіть два різні числа», — випалив Барсик перше, що спало на думку.
- Ми вже говорили з тобою про «недобросовісного» користувача... — зупинив його Маркіз. — Ти краще думай, як вберегти твою програму від подібних проколів...— і, не втримавшись, підказав: — Може, ще щось допишеш? Я маю на увазі в програмному плані, а не у вигляді таблички «Не ходіть по газонах».
- А якщо нам написати ще один рядок... — невпевнено почав Барсик. — Щось таке, чи що, не знаю, що це дасть, напишемо: «If a=b then write (а : 5 : 2, ' = ', b : 5 : 2 ) ;». А ось де тепер його вставити? Вирішив! Напишемо так:
Program Приклад4;
var a,b: Real;
begin
write('Введіть два числа ');
read(а,b);
if a=b then write(а:5 : 2,' = ',b:5:2);
if a>b then write(а:5:2 , ' > v,b;5:2) else write(a:5:2,' < ',b:5:2);
end.
- Рішення, будемо вважати, правильне, — Маркіз був явно задоволений. — І ще ти молодець
- сам вписав умовний оператор, та ще й у неповній формі. Твою програму можна було б записати і так:
Program Приклад4а;
var a,b: Real;
begin
write ('Введіть два числа ') ;
read(a,b);
if a>b then write(а:5:2 ,' > ',b:5:2)
else if a=b then write (a: 5 : 2 , ' =
’ ,b:5:2)
else write (a:5:2,' < ',b:5:2);
end.
- У твоєму варіанті програми, — у Барсика брови поповзли вгору, — говорять, що команди розгалуження записані або виконуються послідовно, а в моєму — що ці команди вложено одна в одну. І ще одне. Ти бачиш, що програма, написана сходу, не завжди правильна, тому-то ми пишемо чорновий варіант тексту не зразу на комп’ютері, аналізуємо його, виправляємо, якщо знайшли помилки або недоліки тощо, виправляємо. Уяви, що ти написав ту свою першу програму, почав її випробовувати, а вона працює некоректно. Ти сидиш, напружено думаєш, перебираєш у голові можливі варіанти правок, а комп’ютер простоює. Зарубай собі на носі, що програмісти більше пишуть на папері, ніж на комп’ютері. Твоя писанина на піску приносить більше користі, ніж сидіння біля комп’ютера, — а далі примирливо: — Взагалі-то, ця задача — відомий в інформатиці алгоритм «Більше з двох», хоча записується трохи інакше. Показати? — і, помітивши в очах товариша питання і згоду, продовжив. Найбільше значення математики називають максимумом, а найменше — мінімумом і позначають відповідно max та min. І максимум і мінімум — числа того ж типу, що й числа послідовності, для якої визначають найбільше чи найменше значення. Отже, програма:
Program Max2; |
Заголовок програми, ім’я якої Мах2 |
var a,b,max:real; |
Змінні дійсного типу |
begin |
Початок |
write('Введіть два числа'); |
Введення аргументів |
read(a,b); |
|
if a>=b then max:=a else max:=b; |
Визначаємо найбільше серед даних, якщо введені числа рівні, то найбільше — будь-яке з них |
write('Найбільше з них ',max:5:2); |
Виведення результату |
end. |
Кінець програми |
- Є питання чи ти все зрозумів? а>=b читають як більше або дорівнює, а два символи а<=b означають менше або дорівнює. Як говоримо, у такій
же послідовності і пишемо символи відношень між числами.
- Питання є, коли тебе немає, — жартома відповів Барсик і знову «заспівав своєї»: — Коли ж ми вже дорвемося до комп’ютера? У нас є вже три робочі програми, а випробувати ніяк не вдається. У мене вже лапи сверблять. Так, так, усі чотири.
- Добре, що не вуса, — відповів Маркіз і запропонував: — Ти краще поміркуй над програмою, яка визначала б більше з трьох різних чисел. Зверни увагу на те, що числа повинні бути різні.
- Якщо а>b і b>с, то а — найбільше... — Барсик сподівався, що ця задача не набагато важча за попередню, тим більше, що він все-таки розв’язав її. Проте Маркіз, скоріше за все, щоб зекономити час, чи з якихось інших міркувань не дав йому закінчити:
- А що буде, коли а>b і с>b? Може статись, що с> а?
- Тоді скажемо так, — Барсик охопила впевненість, — якщо а>Ь і а >с, то число а найбільше, потім... — Барсик на мить замислився і знову впевнено продовжив, — якщо b> а і b > с, то число b найбільше і, врешті-решт, якщо с> а і с>b, то число с найбільше. Отже, я запишу три послідовні команди розгалуження...
- Стривай, а як я запишу, що а>Ь і а>с? Як записати дві умови підряд?
|
|
А |
Not А |
1 |
0 |
0 |
1 |
|
|
А |
В |
A and В |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
А |
В |
A or В |
1 |
1 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
- Ось тут ми й прийшли з тобою до поняття складних умов, — розгладжуючи вуса, промовив Маркіз, а ще якось поважно додав: — Для цього доведеться нам з тобою зайнятися наукою, яка називається «логіка». А тепер — увага! З усього сказаного тобою чи будь-ким іншим можна вибрати речення, про які можна сказати, істинні вони чи хибні. Такі речення ми будемо називати твердженнями. Наприклад, твердження «5 — непарне число» істинне, а твердження «5 — парне число» хибне, а ось про вислів «натуральне число а парне», не знаючи значення а, сказати, істинний він чи ні, не можна. Із простих тверджень, таких як «сьогодні чудовий день», «мене звати Маркіз», за допомогою сполучників «і» та «або» можна утворювати складні твердження і, залежно від істинності
кожного з простих тверджень, визначати істинність складних. У Паскалі, якщо твердження істинне, то говорять true, якщо хибне — false. На практиці істинність і хибність тверджень позначають символами відповідно « + » і «-», а найчастіше приписують значенню true 1, а значенню false — 0. Щоб зекономити час, я познайомлю тебе з таблицями істинності, у яких твердження будемо позначати великими латинськими літерами А і В, їх істинність — 0 або 1, сполучник «і» — латиною and, «або» — or. Колись на дозвіллі на конкретних прикладах, якщо після програмування тебе потягне на логіку, перевіриш. Домовились? А те
пер ще одна логічна операція —- заперечення, латиною not. Тобто якщо твердження А істинне, то його заперечення хибне, і навпаки. Подивись у третю таблицю.
- Дай я трохи розберуся, — заклопотано відповів Барсик. — Можливо, я на перших порах буду користуватися цими таблицями, поки не вивчу або поки не зрозумію. Бідна моя голівонька. Скільки інформації...
- То я тепер можу написати таку програму, — Барсик почав писати, але у п’ятому рядку Маркіз порадив відношення взяти в дужки:
Program МахЗ; |
Заголовок програми з іменем МахЗ |
var a,b,c,max: Real; |
Опис змінних дійсного типу |
Begin |
Початок програми |
write('Введіть три числа') ; |
Блок введення аргументів |
read(a,b,c); |
|
if (a>b) and (a>c) then max:=a; |
Якщо перше число більше за інші, то воно найбільше |
if (b>a) and (b>c) then max:=b; |
Якщо друге число більше за інші, то воно найбільше |
if (c>a) and (c>b) then max:=c; |
Якщо третє число більше за інші, то воно найбільше |
write ('Найбільше з них ',max:5:2); |
Виведення результатів |
end. |
Кінець програми |
- А що робити, якщо користувач введе три рівних числа, я не знаю, — чесно зізнався Барсик.
- Тоді ми змусимо його вводити трійки чисел до тих пір, поки він не стане « законослухняним », — запевнив Маркіз. —• Для цього ми використаємо оператор безумовного переходу, або, як інакше кажуть, оператор переходу на мітку, який записують так: до^ N.
- Це як в операторі вибору case N of? — перепитав Барсик.
- І так, і не так, — відповів Маркіз. — У блоці описів потрібно спочатку оголосити мітку — натуральне число — і тільки після цього можна здійснити перехід на цю мітку. Доречно сказати, що міток може бути кілька. Ось, наприклад, так:
Program МахЗ; |
Заголовок програми з іменем МахЗ |
Label 111; |
Опис мітки 111 |
var a,b,c,max: Real; |
Опис змінних дійсного типу |
begin |
Початок програми |
111:write('Введіть три різних числа'); |
Блок введення аргументів |
read(a,b,с) ; |
|
if (a=b) and (a=c) then goto 111; |
Якщо числа рівні, перейти на мітку 111 і повторити введення аргументів |
if (a>b) and (a>c) then max:=a; |
Якщо перше число більше за інші, то воно найбільше |
if (b>a) and (b>c) then max:=b; |
Якщо друге число більше за інші, то воно найбільше |
if (c>a) and (c>b) then max:=c; |
Якщо третє число більше за інші, то воно найбільше |
write'('Найбільше з них ',max:5:2); |
Виведення результатів |
end. |
Кінець програми |