Рубріки: Теорія

Цикл з передумовою: принцип роботи та приклади коду

Андрій Денисенко

Комп’ютери дуже швидко виконують повторювані дії. Для цього використовується конструкція керування, яка називається циклом. Існує кілька різновидів циклів. Цю статтю присвячено циклу, який виконується, поки зазначена перед ним умова залишається істинною — циклу з передумовою.

Що таке цикл з передумовою

Цикл з передумовою — це послідовність дій, яка повторюється, поки значення вказаної перед нею умови є істинним. У багатьох мовах програмування цей цикл реалізується за допомогою оператора while.

Завдання й принцип роботи циклу з передумовою

Цикл з передумовою застосовується у випадках, коли потрібно:

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

Цикл із передумовою працює за такою схемою:

  • значення умови циклу обчислюється до входу до нього;
  • перед входом перевіряється, чи умова є істинною;
  • якщо її значення хибне, то вхід у цикл не здійснюється і його тіло пропускається;
  • якщо воно є істинним:
    • здійснюється вхід у цикл і виконується тіло циклу;
    • у тілі циклу виконуються дії, одна з яких впливає значення умови;
    • коли інструкції тіла циклу виконано, умова перевіряється знову;
    • якщо значення умови хибне, здійснюється вихід.

Приклади роботи циклу з передумовою

Цикл з передумовою різними мовами програмування виглядає так:

C, C++, C#, Java, JavaScript та інші C-подібні мови

while (<умова>) {
    <тіло циклу>
}

Python

while <умова>:
    <тіло циклу>

Pascal

while <умова> do
begin
    <тіло циклу>
end;

Простий цикл

Розглянемо виконання простого циклу з передумовою докладніше. Припустимо, потрібно виводити в консолі значення змінної i, поки воно менше або дорівнює 7. Мовою Python цей цикл можна записати так:

i = 3 # ініціалізувати змінну циклу
while i <= 7: # повторювати, доки умова істинна
    print(i)
    i += 1 # збільшити значення змінної циклу на одиницю

Вивід буде таким:

3 
4 
5 
6
7

Давайте подивимося, що відбувається під час виконання цього коду.

Ітерація i i <= 7
1 3 True
2 4 True
3 5 True
4 6 True
5 7 True
6 8 False
  • Ітерація 1. Спочатку змінна i містить значення 3, тому умова i <= 7 рівна True. Здійснюється вхід у тіло циклу. Виводиться значення i (3), потім воно збільшується на 1. Цикл запускається знову.
  • Ітерація 2. Тепер змінна i містить значення 4, тому умова i <= 7 рівна True. Виконується вхід у тіло циклу. Виводиться значення i (4), потім воно збільшується на 1. Цикл знову запускається.
  • Ітерація 3. Тепер змінна i містить значення 5, тому умова i <= 7 рівна True. Виконується вхід у тіло циклу. Виводиться значення i (5), потім воно збільшується на 1. Цикл запускається знову.
  • Ітерація 4. Тепер змінна i містить значення 6, тому умова i <= 7дорівнюєTrue. Виконується вхід у тіло циклу. Виводиться значення i (6), потім воно збільшується на 1. Цикл запускається знову.
  • Ітерація 5. Тепер змінна i містить значення 7, тому умова i <= 7дорівнюєTrue. Виконується вхід у тіло циклу. Виводиться значення i (7), потім воно збільшується на 1. Цикл запускається знову.
  • Ітерація 6. Тепер змінна i містить значення 8, тому умова i <= 7 дорівнює False. Оскільки умова не істинна, відбувається вихід із циклу.

Обчислення факторіалу

Розглянемо роботу циклу з передумовою на прикладі обчислення факторіалу.

Факторіал числа — це добуток усіх натуральних чисел до цього числа включно.

Формула факторіалу має такий вигляд:

n! = 1 * 2 * … * n

Тут число — це n, а його факторіал — n!.

Факторіал одиниці є одиницею, і у випадку, коли n = 1, обчислення робити не потрібно. Тому для обчислення факторіалу підійде цикл із передумовою n > 1. Це означає, що вихід із циклу відбудеться, коли n дорівнюватиме 1. Для цього потрібно перебрати числа у зворотному порядку, починаючи з n, і після проведення обчислень зменшувати значення n на 1, таким чином змінюючи значення умови циклу.

Приклад коду для обчислення факторіалу на Python

# Get N from the user and convert into an integer.
n = int(input("Enter N to calculate N!: "))

# Initialize the result value
factorial = 1

# Check if the loop should be executed
while n > 1:
    # Calculate the result for this iteration
    factorial *= n

    # Decrease N to get the value for the next iteration
    # or to exit if n is not greater than 1
    n -= 1

# Print the resulting value
print(f"N! = {factorial}")

Приклад коду для обчислення факторіалу мовою Java

import java.util.*;

class Factorial
{
    public static void main (String[] args) throws java.lang.Exception
    {
        System.out.print("Enter N to calculate N!: ");
        Scanner scanner = новий Scanner (System.in);
        int n = scanner.nextInt();
        int factorial = 1;
        while (n > 1) {
            factorial *= n;
            n--;
        }
        System.out.println("N! = "+ factorial);
        System.console().readLine();
    }
}

Ігровий цикл

Ще одним прикладом використання циклу з передумовою може стати гра.

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

Приклад коду гри з киданням кубика на Python

# Import random module to "roll a die"
import random

def greet():
    """Greets a user once the game is started"""
    print()
    print("*" * 52)
    print("Welcome to The Roll A Die Game")
    print("*" * 52)

def continue_game():
    """Checks if the user entered Y/y - що forms the game loop precondition"""
    print()
    return input("Enter 'Y' для roll a die or anything else to exit: ") in ['Y', 'y']

def game_loop():
    """Executes the game loop"""

    # Get user input and check for errors
    guess = 0
    try:
        guess = int(input("Your guess: "))
    except:
        guess = 0

    if guess not in range(1, 6):
        print("Wrong value. Must be from 1 to 6.")
    else:
        # User input lies between 0 and 7. Roll a die.
        r = random.randint(1, 6)

        # Answer the user
        if r == guess:
            print(f"You win! It's {r}")
        else:
            print(f"You lose! It's {r}")

def main():
    # Greet the user
    greet()

    # Check the precondition
    while continue_game():
        # Execute the loop body if the precondition is satisfied
        game_loop()

if __name__ == '__main__':
    main()

Результат:

Цикл з порожнім тілом

Цикл може бути «пустотілим». Такі цикли використовуються, коли обчислення здійснюються в умові циклу, як у цьому прикладі на Java:

import java.util.*;
class Average
{
    public static void main (String[] args)
    {
        int i, j;
        i = 20;
        j = 40;

        while (++i < --j) // Values ​​are incremented and decremented in the condition
            ;
        System.out.println("Average is" + i);
    }
}

У цьому прикладі перед кожним обчисленням умови циклу проводиться збільшення i на одиницю і зменшення j на одиницю. Це робиться за допомогою преінкременту (++i) та передекременту (--j).

Порожній цикл можна використовувати і для читання файлу, як у прикладі на Python.

Допустимо, є файл з програмним кодом на Python. Потрібно читати його рядок за рядком, пропускаючи початкові рядки з коментарями (починаються з символу #). Це можна зробити за допомогою такого коду:

with open(fileName, 'r') as f:
      while f.readline().startswith("#"):
              pass

Випадки, коли тіло циклу ніколи не виконується

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

Приклад на Java:

import java.util.*;

class FalseCondition
{
    public static void main (String[] args)
    {
        boolean continueExecuting = false;

        while (continueExecuting) {
            System.out.println("This should never happen!");
        }
        System.out.println("This should be printed.");
    }
}

Приклад на Python:

continueExecuting = False

while continueExecuting:
    print("This should never happen!")

print("This should be printed.")

В результаті виконання будь-якого з цих прикладів у консолі буде виведено рядок This should be printed. Рядок This should never happen! виводитися не буде.

Нескінченний цикл

Якщо виконано вхід у тіло циклу, але в ньому ніщо не впливає на значення умови, цикл повторюватиметься нескінченно. Іноді таку ситуацію називають зациклюванням.

Приклад на Java:

import java.util.*;

class InfiniteLoop
{
    public static void main (String[] args)
    {
        boolean continueExecuting = true;
        while (continueExecuting) {
            System.out.println("It is happening again.");
        }
        System.out.println("This should never happen.");

    }
}

Приклад на Python:

continueExecuting = True

while continueExecuting:
    print("It is happening again.")

print("This should never happen.")

У цьому прикладі змінній continueExecuting присвоюється значення True перед виконанням циклу, але воно не змінюється в його тілі. Виконання цього циклу не припиняється.

Такі цикли спричиняють нестабільність програм, але нерідко застосовуються на практиці. Це можливо завдяки конструкціям, які дозволяють здійснювати вихід із циклу. До того ж, для виходу може використовуватись сторожовий таймер.

Примусовий вихід із циклу

Нескінченні цикли використовуються, наприклад, у сценаріях, що управляють ігровими персонажами, і як цикли обробки повідомлень у програмах з віконним інтерфейсом. Для виходу з них можна використовувати оператор break.

Розглянемо приклад програми з циклом обробки повідомлень мовою C:

while (1)
{
    bRet = GetMessage(&msg, NULL, 0, 0);

    if (bRet > 0) // (Such a message must be processed.)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else if (bRet < 0) // (Return code -1 indicates an error.)
    {
        // Handle the error.
        // ...
    }
    else // (Return code 0 indicates "exit".)
    {
        break;
    }
}

У цьому фрагменті:

  • запускається нескінченний цикл (1 сприймається як булевське значення true);
  • приймається повідомлення, і в залежності від нього здійснюється розгалуження:
    • якщо значення, повернене функцією GetMessage (код виходу), більше за нуль, то він відповідає повідомленню, яке потрібно обробити;
    • якщо код виходу менший за нуль, то сталася помилка, і її потрібно обробити, а потім, можливо, вийти з програми;
    • якщо код виходу дорівнює нулю, то здійснюється вихід із програми за допомогою оператора break.

Коли в циклі використовується змінна та її значення змінено в такий спосіб, щоб значення умови стало хибним, то цикл виконується до кінця.

Оператор break використовується для примусового виходу з циклу після рядка з цим оператором.

Особливості циклу з передумовою

Порівняємо цикл із передумовою з іншими видами циклів:

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

Висновок

Отже, цикл із передумовою використовується, коли потрібно повторювати послідовність дій, якщо і поки дотримується умова.

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

Деякі мови дозволяють використовувати цикл із порожнім тілом. У цій конструкції обчислення виконуються в умові циклу.

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

Останні статті

EXMO.com збільшила ставки для ETH, USDT та USDC: заробляйте до 5% і 9% на рік з найпопулярніших альткоїнів!

Популярна криптобіржа EXMO.com підняла річні ставки на ETH, USDT та USDC у програмі Earn. Отримуйте…

15.05.2024

MacPaw запустила бету маркетплейса Setapp Mobile для iOS в ЄС

Українська компанія MacPaw випустила новий маркетплейс Setapp Mobile. Доступний він в бета-версії та лише за…

15.05.2024

Вінницькі розробники створили автономний рій FPV, який знищує цілі без участі операторів

Одна з команд вінницьких розробників FPV створила плату автономного польоту та спеціальний застосунок. Це дозволило…

15.05.2024

В експериментальному режимі: е-кабінет військовозобов’язаного запрацює вже через пару днів

Електронний кабінет військовозобов’язаного запрацює вже 18 травня. Але поки в експериментальному режимі — через те,…

14.05.2024

Чип Neural Engine, штучний інтелект, покращена камера: чого чекати від iPhone 16

Презентація Apple, де компанія анонсує нові продукти та розповідає про оновлення айфонів, – завжди очікувана…

13.05.2024

Розробники хочуть створити «Дія. Канали» — альтернативу Telegram та іншим месенджерам

Розробники ГО «Аналітичний центр Інформаційних ресурсів» планують створити альтернативу Telegram та іншим месенджерам — «Дія.…

13.05.2024