Головна |
Оператор безумовного переходуІз завданням дострокового виходу з кратних циклів зв'яжемо вивчення раніше невикористаного нами оператора безумовного переходу. Його загальний вигляд наступний: goto мітка; Тут Метка - спеціальним чином вказане місце в програмі. Дія goto дуже просто: незалежно від будь-яких умов він здійснює передачу управління на оператор, наступний за міткою. Кожна мітка має вигляд m: де m - ім'я, побудоване за звичайними правилами або целочисленная константа від 0 до 9999 включно. Мітку недостатньо поставити перед потрібним оператором - її потрібно ще й оголосити в розділі описів оператором label m ;. Можна оголосити і кілька міток відразу, розділивши їх імена комами. Прийнято розташовувати оператор опису міток до оператора var. Таким чином, мітки і оператор goto дозволяють вирішити задачу швидкого безпосереднього переходу до потрібного місця в програмі: label 10,20; var i, j: integer; begin write ('Введіть значення I (i> 2)'); readln (i); if i <3 then goto 10; j: = 2; 20: if i mod j = 0 then write (j, ''); j: = j + 1; if j 10: end. Ця нескладна програма дозволяє користувачеві ввести число i, більше двох, після чого друкує все числа від 2 до i-1, на які i ділиться без залишку (перевірка залишку від ділення i на j виконана операцією mod). У разі введення користувачем неприпустимого значення i (меншого трьох) відбувається перехід на мітку 10 :, розташовану перед закриває оператором end. - Таким чином, програма відразу ж завершується. Мітка 20: дозволяє організувати цикл без використання операторів while, repeat або for. Дійсно, перед міткою 20: змінна j отримує початкове значення 2, потім, якщо i ділиться на j без залишку, значення j виводиться на екран, потім збільшується на одиницю і, якщо значення i не досягнуто, відбувається перехід на мітку 20 :, яка перевіряє вже нове значення j. Однак, і тієї, і іншої мети можна було досягти без використання goto, застосовуючи тільки оператори циклу і break ;. З правомірністю використання простого оператора goto пов'язані складні і багаторічні суперечки. Безсумнівно, що програму завжди можна написати, не вдаючись до goto (іноді структурне програмування називають навіть "програмуванням без goto"), не викликає сумніву також, що використання міток і goto порушує і ускладнює сприйняття структури програми людиною. Однак автору видається надмірним вимога вигнати goto зовсім - в ряді ситуацій він просто зручніше, ніж інші засоби. Уявімо, що нам потрібно достроково вийти з подвійного (або взагалі кратного) циклу. Оператор break ;, розташований у внутрішньому циклі, перерве його виконання, але виконання зовнішнього циклу продовжиться з наступного кроку. Без goto вийти "з усіх циклів відразу" можна хіба що з застосуванням спеціальних змінних-прапорів: var Flag: boolean; {Змінна-прапор} ... Flag: = false; {Прапор встановлений в "брехня"} while true do begin {зовнішній цикл} while true do begin {внутрішній цикл} ... if Умова then begin {Сталося щось, що вимагає виходу з обох циклів відразу} Flag: = true; {Ставимо прапор, повідомляючи зовнішньому циклу, що потрібно завершення} break; {Вихід з внутрішнього циклу} end; end; if Flag = true then break; {Зовнішній цикл на кожному кроці повинен відслідковувати стан прапора} end; Якщо цикл потрійний - при такому підході знадобиться вже два прапора, і так далі. Альтернативний шлях - встановити максимальні значення керуючих змінних зовнішніх циклів - також не відповідає канонам структурного програмування. З goto все виглядає простіше і природніше: label go1; ... while true do begin while true do begin ... if Умова then goto go1; {Вийшли з двох циклів відразу!} end; end; Go1: ... Другий аспект можливого використання goto пов'язаний з написанням складних підпрограм (Див. Гл. 18), здатних завершуватися в різні моменти свого виконання. Найчастіше зручніше, щоб підпрограма мала всього одну "точку виходу" - свій останній оператор, а достроковий вихід здійснюється установкою значення, що повертається і переходом на останній оператор за допомогою goto. Обмеження на використання goto наступні: мітка повинна знаходитися в тому ж блоці програми, що і оператор goto. Таким чином, не можна перейти з однієї частини складної програми (такий, як процедура або функція, Що вивчаються в гл. 18) в іншу. Безсумнівно, що ці обмеження введені розроблювачами, щоб не ускладнювати і без того складне сприйняття програм, які зловживають даними оператором. Директиви компілятора і обробка помилок введення | Оператор циклу. Цикли з передумовою та умовою поста | Цикл з лічильником і дострокове завершення циклів | алгоритм табулирования | Алгоритм організації лічильника | Алгоритми накопичення суми і твори | Типові алгоритми пошуку максимуму і мінімуму | Рішення навчальних завдань на цикли | Одномірні масиви. Опис, введення, висновок і обробка масивів на Паскалі | Рішення типових задач на масиви | |