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

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

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

Компьютеры очень быстро выполняют повторяющиеся действия. Для этого используется управляющая конструкция, которая называется циклом. Существует несколько разновидностей циклов. Эта статья посвящена циклу, который выполняется, пока истинно указанное перед ним условие — цикл с предусловием.

Что такое цикл с предусловием

Цикл с предусловием — это последовательность действий, которая повторяется, пока значение указанного перед ней условия истинно. Во многих языках программирования этот цикл реализуется с помощью оператора 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 = new 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 - that forms the game loop precondition"""
    print()
    return input("Enter 'Y' to 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:
        # The user input lies between 1 and 6. Roll the dice.
        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 устанавливается в истинное перед выполнением цикла, но не изменяется в его теле. Выполнение этого цикла не прекращается.

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

Принудительный выход из цикла

Бесконечные циклы используются, например, в сценариях, управляющих игровыми персонажами, и в качестве циклов обработки сообщений в программах с оконным интерфейсом. Для выхода из них можно использовать оператор 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.

Некоторые языки позволяют использовать цикл с пустым телом. В этой конструкции вычисления выполняются в условии цикла.

Если в теле цикла ничто не изменяет истинность его условия, цикл может повторяться без конца. Бесконечные циклы используют в играх, программах с оконным интерфейсом и в других случаях, когда требуется повторять действия, пока цикл не будет прерван извне.

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

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023