Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Цикл з виходом з середини






Цикл з виходом з середини — найзагальніший тип умовного циклу. Синтаксично такий цикл оформляється за допомогою трьох інструкцій: початок циклу, кінець циклу та інструкції (команди) виходу з циклу. Інструкція початку позначає точку програми, з якої починається тіло циклу, інструкція кінця — точку, де тіло закінчується. Всередині тіла має бути присутня команда виходу з циклу, при виконанню якої цикл завершується і керування передається на оператор, наступний після інструкції кінця циклу. Природньо, щоб цикл виконався більш ніж один раз, команда виходу має викликатися не безумовно, а тільки при виконанні умови виходу.

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

Легко побачити, що за допомогою циклу з виходом з середини легко утворити як цикл з передумовою (розташувавши команду виходу на початку тіла циклу), так і цикл з післяумовою (розташувавши команду виходу в кінці тіла циклу).

Частина мов програмування містить особливі інструкції для утворення циклу з виходом з середини. Так, у мові Ада для цього використовується конструкція LOOP … END LOOP і команда виходу EXIT або EXIT WHEN:

LOOP... Частина тіла циклу EXIT WHEN < умова виходу>;... Частина тіла циклу IF < умова виходу> THEN EXIT; END;... Частина тіла циклу END LOOP:

Тут всередині циклу може бути будь-яка кількість команд виходу обох типів. Самі команди виходу принципово не відрізняються, зазвичай EXIT WHEN застосовують, коли перевіряється тільки умова виходу, а просто EXIT — коли вихід з циклу здійснюється в одному з варіантів складного умовного оператора.

У тих мовах, де подібних конструкцій не передбачено, цикл з виходом з середини може бути побудований за допомогою будь-якого умовного циклу та інструкції дострокового виходу з циклу (такого, як break в Сі, exit вТурбо Паскалі т.п.), або інструкції безумовного переходу goto.

Цикл з лічильником

Цикл з лічильником — цикл, в якому деяка змінна змінює своє значення від заданого початкового значення до кінцевого значення з деяким кроком, і для кожного значення цієї змінної тіло циклу виконується один раз. В більшості процедурних мов програмування реалізується оператором for, в якому вказується лічильник (так звана «змінна циклу»), потрібна кількість проходів (або граничне значення лічильника) і, можливо, крок, з яким змінюється лічильник. Наприклад, в мові Оберон-2 такий цикл має вигляд:

FOR v: = b TO e BY s DO... тіло циклу END

(тут v — лічильник, b — початкове значення лічильника, e — межове значення лічильника, s — крок).

Неоднозначне питання про значення змінної по завершенні циклу, в якому ця змінна використовувалась як лічильник. Наприклад, якщо в програмі на мові Паскаль зустрінеться конструкція виду:

i: = 100; for i: = 0 to 9 dobegin... тіло циклу end; k: = i;

виникає питання: яке значення буде в підсумку присвоєне змінній k: 9, 10, 100, може якесь інше? А якщо цикл завершиться достроково? Відповіді залежать від того, чи збільшується значення лічильника після ітерації і чи не змінює транслятор це значення додатково. Ще одне запитання: що буде, якщо всередині циклу лічильнику буде явно присвоєне нове значення?

Різні мови програмування мають різні підходи до цього питання. В деяких поведінку лічильника чітко регламентовано. В інших, наприклад, Паскалі, стандарт мови не визначає ані кінцевого значення лічильника, ані наслідків його явної зміни в циклі, але не радиться змінювати значення лічильника явно і використовувати його після завершення циклу без повторної ініціалізації. Програма на Паскалі, що ігнорує цю пораду, матиме невизначену поведінку, тобто може давати різні результати при виконанні на різних системах чи при використанні різних трансляторів або навіть різних режимів оптимізації одного й того ж транслятора.

Радикально вирішене питання в мові Ада: лічильник вважається описаним в заголовку циклу та поза циклом просто не існує. Навіть якщо ім’я лічильника вже використовується в програмі, всередині циклу в якості лічильника використовується окрема змінна. Лічильнику заборонено явно присвоювати будь-які значення, він може змінюватись лиш внутрішнім механізмом оператора циклу. В результаті конструкція

i: = 100; for i in (0..9) loop... тіло циклу end loop; k: = i;

зовнішньо аналогічна вищенаведеному циклу на Паскалі, трактується однозначно: змінній k буде присвоєно значення 100, оскільки змінна i, використовувана поза межами даного циклу, не має жодного стосунку до лічильника циклу i, який змінюється всередині циклу. Подібне відокремлення лічильника зручне і безпечне: не потрібен окремий опис для нього та мінімізується ймовірність випадкових помилок, пов’язаних із випадковим руйнуванням зовнішніх стосовно циклу змінних. Якщо програмісту потрібно включити в готовий код цикл з лічильником, то його не турбує чи існує змінна з ім’ям, яке він обрав для лічильника, і йому не потрібно додавати опис свого лічильника. Він просто пише код зі змінною-лічильником, ім’я якої йому зручне, і може бути впевненим, що ніякої колізії імен не відбудеться.

Цикл з лічильником завжди можна написати як умовний цикл, перед початком якого лічильнику присвоюється початкове значення, а умовою виходу з циклу є досягнення лічильником кінцевого значення; в тіло циклу при цьому додається оператор зміни лічильника на потрібний крок. Однак спеціальні оператори циклу з лічильником можуть ефективніше транслюватися, бо формалізований вигляд такого циклу дозволяє використовувати спеціальні процесорні команди організації циклів.

В деяких мовах, наприклад, Сі та інших, похідних від неї, цикл for, незважаючи на синтаксичну форму циклу з лічильником, в дійсності є циклом з передумовою. Тобто в Сі конструкція циклу:

for (i = 0; i < 10; ++i){... тіло циклу}

фактично являє собою інший варіант запису конструкції[1]:

i = 0; while (i < 10){... тіло циклу ++i; }

Тобто в конструкції for спочатку пишеться довільне речення ініціалізації циклу, потім — умова продовження і, насамкінець, виконувана після кожного тіла циклу деяка операція (це не обов’язково має бути зміна лічильника; це може бути модифікація вказівника або будь-яка зовсім стороння дія). Для мов такого типу вищезазначена проблема розв'язується дуже просто: змінна-лічильник поводиться цілком передбачувано і по завершені циклу зберігає своє останнє значення.



Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2026 год. (0.188 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал