Звідки беруться “зациклені” цикли

Програмісти-початківці, кодуючи алгоритми циклічної структури, часто припускаються логічних помилок, які призводять до нескінченних повторів циклу – “зациклень”, як ми їх звикли називати у повсякденному житті. Наведемо характерні приклади найбільш типових причин таких ситуацій.

В більшості підручників з програмування при розгляді циклів з перед- чи після умовою зазначають наступне: “для того, щоб виконання циклу було успішно завершене , необхідно, щоб оператори в тілі циклу змінювали значення змінних, що порівнюються в умові”. Наприклад, якщо потрібно скласти табицю квадратів натуральних чисел від 11 до 20, використовуючи оператор циклу While. Макрос


Sub CycleSample1()
Dim S As String
k = 11
S = ””
While k <= 20
S = S & k^2
Wend
MsgBox S
End Sub

буде працювати. Але вічно і безрезультатно, оскільки в тілі циклу пропущена команда
k = k + 1
Значення k залишиться рівним 11 після кожного наступного виконання тіла циклу, відповідно, забезпечується умова продовження циклу
k <= 20, яка вказує, що тіло циклу необхідно виконати ще раз.

Ще один приклад “вічного” While-у із менш помітною логічною помилкою. Наступний макрос повинен створювати таблицю значень функції y = cos3x на відрізку [0,3] з кроком 0.3.


Sub CycleSample2()
Dim S As String
x = 0
S = ””
While x <= 3
S = S & ”x = ” & x & ” y = ” & Cos(x) ^ 3 & Chr(13)
x = x + h
Wend
MsgBox S
End Sub

Транслятори інших мов програмування такий код не виконали б, оскільки в ньому не описані змінні x та h, але Basic допускає неявний опис змінних і такий макрос запускатиметься на виконання, проте не дасть результату. Причина в тому що змінній h не присвоєно жодного значення (в більшості випадків її значення буде рівне 0 і кожний повтор циклу буде виконуватися знову для x = 0

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


For n = 1 To 10
‘Команди тіла циклу
n = n1
Next n

оператор For після кожного проходу циклу збільшуватиме значення лічильника n на 1, а оператор присвоєння
n = n1
зменшуватиме на 1, повертаючи попереднє значення. Отримаємо ще один нескінченний цикл.

Ще один спосіб отримання “вічного” циклу криється у використанні добових значень параметра циклу. Якщо описати лічильник циклу For як змінну цілого типу, а збільшувати його значення на дробовий крок, то за рахунок приведення типів можна отримати нескінченний цикл із сталим значенням параметра. Наприклад, в наступному фрагменті лічильник циклу n отримує початкове значення 1. Після завершення тіла циклу значення n збільшується на 0.5 мало б стати 1.5, але оскільки змінну n описано як цілочисельну змінну, то дробова частина значення відкидається, і n отримує значення 1. Ця ж ситуація буде повторюватися на кожному наступному повторі циклу.


Dim n As Integer
For n = 1 To 5 Step 0.5
‘Команди тіла циклу
Next n

Зациклення макроса не завжди замітне для користувача, оскільки макроси OpenOffice.org, зазвичай, не блокують роботу користувача з документом. Але якщо з середовища редактора OOo Basic не вдається запустити на виконання жоден макрос, то це означає, що транслятор не завершив роботу з попереднім макросом, в т.ч. і через зациклення. Для екстренного переривання роботи макроса на панелі інструментів редактора передбачена кнопка “Зупинити макрос” та комбінація клавіш Shift+F5.

Залишити відповідь