🐹 Go

Цикл while и do-while в Go 1.21: подробное руководство

Цикл while и do-while в Go

Зачем нужны циклы?

Представь, что тебе нужно 100 раз написать на доске: «Я — молодец». Это скучно и долго. Циклы в программировании позволяют повторять одно и то же действие много раз, пока выполняется какое-то условие. Сегодня мы познакомимся с двумя видами циклов: while и do-while.

Цикл while (пока)

Цикл while работает так: «Пока условие верно — делай действие». Как только условие перестаёт быть верным, цикл заканчивается. В языке Go нет ключевого слова while, но его роль выполняет обычный цикл for с одним условием.

Синтаксис:

for условие {
    // код, который повторяется
}

Пример 1: Обратный отсчёт

Доктор Элара Вэнс запускает машину времени с начальной координаты n. Каждую секунду координата уменьшается на 1. Напишем программу, которая выведет обратный отсчёт от n до 0.

package main

import "fmt"

func main() {
    var n int
    fmt.Print("Введите начальную координату: ")
    fmt.Scan(&n)

    for n >= 0 {
        fmt.Println("Текущая координата:", n)
        n-- // уменьшаем на 1
    }
    fmt.Println("Запуск!")
}

Ввод: 5
Вывод:
Текущая координата: 5
Текущая координата: 4
Текущая координата: 3
Текущая координата: 2
Текущая координата: 1
Текущая координата: 0
Запуск!

Цикл do-while (делай-пока)

В Go нет специального цикла do-while, но его можно сделать с помощью for с условием после тела. Главное отличие: тело цикла выполняется хотя бы один раз, даже если условие сразу ложное. Сначала делаем действие, потом проверяем условие.

Синтаксис (имитация):

for {
    // код, который выполняется
    if !условие {
        break
    }
}

Пример 2: Секретный агент

Агент получает зашифрованные коды. Нужно обрабатывать их, пока не встретится код 0 (стоп-сигнал). Даже если первый код — 0, его нужно обработать.

package main

import "fmt"

func main() {
    var code int
    fmt.Println("Вводите коды (0 — стоп):")

    for {
        fmt.Scan(&code)
        if code == 0 {
            fmt.Println("Миссия завершена!")
            break
        }
        fmt.Println("Обработан код:", code)
    }
}

Ввод: 5 8 3 0
Вывод:
Вводите коды (0 — стоп):
Обработан код: 5
Обработан код: 8
Обработан код: 3
Миссия завершена!

Разбор типичных задач

Задача 1: Робот-шахтёр

Робот собирает кристаллы, пока энергия в сумке не станет >= 100. Каждый кристалл даёт случайное количество энергии от 10 до 30. Нужно выводить текущий запас энергии после каждого шага.

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    energy := 0
    rand.Seed(42) // для повторяемости

    for energy < 100 {
        crystal := rand.Intn(21) + 10 // от 10 до 30
        energy += crystal
        fmt.Printf("Собран кристалл: +%d энергии. Всего: %d\n", crystal, energy)
    }
    fmt.Println("Сумка полна! Энергия:", energy)
}

Вывод:
Собран кристалл: +26 энергии. Всего: 26
Собран кристалл: +29 энергии. Всего: 55
Собран кристалл: +20 энергии. Всего: 75
Собран кристалл: +29 энергии. Всего: 104
Сумка полна! Энергия: 104

Задача 2: Юный садовод

Алекс посадил росток высотой h. Каждый день он увеличивается в k раз. Нужно узнать, через сколько дней он достигнет нужной высоты H. Используем do-while, потому что проверять нужно после первого дня.

package main

import "fmt"

func main() {
    var h, k, H int
    fmt.Print("Начальная высота: ")
    fmt.Scan(&h)
    fmt.Print("Во сколько раз увеличивается: ")
    fmt.Scan(&k)
    fmt.Print("Желаемая высота: ")
    fmt.Scan(&H)

    days := 0
    current := h

    for {
        days++
        current *= k
        fmt.Printf("День %d: высота %d см\n", days, current)
        if current >= H {
            break
        }
    }
    fmt.Printf("Росток достиг высоты %d см за %d дней\n", current, days)
}

Ввод: 5 3 100
Вывод:
Начальная высота: 5
Во сколько раз увеличивается: 3
Желаемая высота: 100
День 1: высота 15 см
День 2: высота 45 см
День 3: высота 135 см
Росток достиг высоты 135 см за 3 дней

Частые ошибки новичков

  • Бесконечный цикл: Забыли изменить переменную в условии. Например, не написали n-- в обратном отсчёте — цикл будет работать вечно.
  • Неправильное условие: Путают > и >=. В задаче с роботом, если написать energy > 100, цикл закончится, когда энергии станет 101, а не 100.
  • Забытый break: В имитации do-while обязательно нужен break, иначе цикл никогда не остановится.
  • Сканирование в цикле: Если не обработать неверный ввод, программа может «зависнуть».

Итоговый пример: Волшебная экспедиция

Юный исследователь нашёл Артефакт Силы. Он начинает светиться, и каждую секунду его сила увеличивается вдвое. Нужно определить, через сколько секунд сила артефакта превысит 1000 единиц. Начальная сила — 1.

package main

import "fmt"

func main() {
    power := 1
    seconds := 0

    fmt.Println("Артефакт активирован!")
    fmt.Printf("Секунда %d: сила = %d\n", seconds, power)

    for power <= 1000 {
        seconds++
        power *= 2
        fmt.Printf("Секунда %d: сила = %d\n", seconds, power)
    }

    fmt.Printf("Артефакт достиг силы %d за %d секунд!\n", power, seconds)
}

Вывод:
Артефакт активирован!
Секунда 0: сила = 1
Секунда 1: сила = 2
Секунда 2: сила = 4
Секунда 3: сила = 8
Секунда 4: сила = 16
Секунда 5: сила = 32
Секунда 6: сила = 64
Секунда 7: сила = 128
Секунда 8: сила = 256
Секунда 9: сила = 512
Секунда 10: сила = 1024
Артефакт достиг силы 1024 за 10 секунд!

Теперь ты знаешь, как использовать циклы while и do-while в Go. Помни: while проверяет условие перед выполнением, а do-while — после. Выбирай тот, который лучше подходит для твоей задачи!