Цикл
Допустим у вас 10 яблок, 2 руки и один нож. В жизни вы последовательно чистите весь десяток, руководствуясь одним и тем же алгоритмом. А как заставить программу делать повторяющееся действие с каждым яблоком?
Внешне операторы разные, но устроены они одинаково: любой цикл ![Таблица Пифагора с обложки школьной тетради: множители от 2 до 9 и их произведения]()
while в Java это оператор, который повторяет блок кода до тех пор, пока логическое условие остается истинным. Условие проверяется перед каждым проходом, поэтому тело цикла может не выполниться ни разу. У цикла есть вторая форма, do-while: она сначала выполняет тело и только потом проверяет условие, то есть гарантирует минимум один проход.Кратко
while (условие) { ... }проверяет условие до каждого прохода, поэтому тело может не выполниться ни разу. Это цикл с предусловием.do { ... } while (условие);проверяет условие после тела, поэтому тело выполняется минимум один раз. Это цикл с постусловием.breakнемедленно выходит из цикла,continueпропускает остаток тела и возвращает управление к проверке условия.while (true)это бесконечный цикл: выход из него организуют командойbreakпо внешнему событию.- Циклы можно вкладывать друг в друга: внутренний цикл полностью отрабатывает на каждом шаге внешнего.
- За изменением переменной из условия следит сам программист. Если в теле она не меняется, программа зависнет.
Введение
Наши самые первые программы представляли собой последовательность инструкций, которые выполняются одна за другой. Без развилок. Это и HelloWorld, выводящий в консоль фразу приветствия, арифметические вычисления. После первых программ мы научились ветвлению, то есть программа выполняла те или иные действия в зависимости от условий. Вот как можно было бы закодировать включение кондиционера на обогрев и охлаждение:
if (tempRoom>tempComfort)
airConditionerOn();
if (tempRoom<tempComfort)
heaterOn();
Сделаем следующий шаг. В быту мы часто выполняем однообразные повторяющиеся действия, например, чистим яблоки для пирога. Этот увлекательный процесс можно описать как:
Если в тазике есть яблоки, то выполняем шаги с 1.1 по 1.4:
- 1.1. Берем яблоко
- 1.2. Чистим и нарезаем его дольками
- 1.3. Помещаем на основание пирога из теста на сковороде
- 1.4. Возвращаемся на шаг 1.

- Привяжем себя к числу яблок, но если у нас их мало, часть команд выполнялась бы вхолостую без «полезной нагрузки» (и, возможно, порезались, очищая кожуру несуществующего яблока).
- Если яблок больше, чем наших команд обработки, часть продуктов пропала бы необработанной.
- Подобный «код» тяжело читать, в нем много повторов, его трудно модифицировать.
Циклы: операторы многократного выполнения действий
Цикл while Java (цикл вайл) хорошо подойдет в нашем случае. Эта конструкция оформляет многократные действия в лаконичную и понятную структуру. Алгоритм по нарезке яблок для пирога в виде while в Java мог бы выглядеть как:
while(числоЯблокВТазике>0) {
яблоко = тазик.взятьОчередноеЯблоко();
положитьВПирог(яблоко.чистить().нарезать());
числоЯблокВТазике--;//-- это декремент, уменьшает количество яблок на единицу
}
System.out.println("Яблоки для пирога обработаны.");
Синтаксис команды
Первый способ описания оператора while следующий:
while(Логическое выражение) {
// Тело цикла - периодически выполняемые оператор(ы)
}
Выполняется следующим образом (по шагам):
- Вычисляем Логическое условие, следующее в скобках за while.
- Если логическое условие истинно, то выполняются операторы в теле цикла, после выполнения последнего оператора в теле цикла, переходим на шаг 1
- Если логическое условие ложно, то переходим к первому оператору за пределами цикла while.
Цикл с предусловием
Так как перед выполнением тела цикла мы всегда предварительно вычисляем логическое выражение (условие входа в цикл), то этот вид while часто называют циклом с предусловием. Построим таблицу первых десяти целых, положительных степеней числа. Шаг цикла задает инкрементpower++:
public static void main(String[] args) {
int number = 3; // Возводимое в степень число
int result = 1; // Результат возведения в степень
int power = 1; // Начальный показатель степени
while(power <= 10) { // условие входа в цикл
result = result * number;
System.out.println(number + " в степени " + power + " = " + result);
power++;
}
}
Результат вывода на консоль:
3 в степени 1 = 3
3 в степени 2 = 9
3 в степени 3 = 27
3 в степени 4 = 81
3 в степени 5 = 243
3 в степени 6 = 729
3 в степени 7 = 2187
3 в степени 8 = 6561
3 в степени 9 = 19683
3 в степени 10 = 59049
Process finished with exit code 0
Цикл с постусловием
Второй вид цикла:
do {
// Тело цикла - периодически выполняемые оператор(ы)
}while (Логическое выражение);
Выполняется следующим образом (шаги):
- Выполняется тело цикла (сразу после ключевого слова do).
- Вычисляем Логическое условие, следующее в скобках за while.
- Если логическое условие истинно, то переходим на шаг 1
- Если логическое условие ложно, то переходим к первому оператору за пределами цикла while.
public static void main(String[] args) {
int number = 3;// Возводимое в степень число
int result = number;// Результат возведения в степень
int power = 1;// Начальный показатель степени
do {
System.out.println(number + " в степени " + power + " = " + result);
power++;
result = result * number;
}while (result < 10000); // условие выхода из цикла
}
Результат вывода на консоль:
3 в степени 1 = 3
3 в степени 2 = 9
3 в степени 3 = 27
3 в степени 4 = 81
3 в степени 5 = 243
3 в степени 6 = 729
3 в степени 7 = 2187
3 в степени 8 = 6561
Process finished with exit code 0
Обратите внимание на изменения в коде, сравнив с вариантом цикла с предусловием.while, do-while и for: чем отличаются
Три оператора цикла решают одну задачу, но удобны в разных ситуациях:| Оператор | Когда проверяется условие | Сколько раз выполнится тело | Типичная задача |
|---|---|---|---|
while | до тела цикла | от 0 раз | число повторов заранее неизвестно: чтение до конца файла, ожидание события |
do-while | после тела цикла | от 1 раза | действие нужно выполнить хотя бы раз: запросить ввод и проверить его |
for | до тела цикла, счетчик объявлен в заголовке | от 0 раз | число повторов известно: перебор массива или коллекции по индексу |
for можно записать через while, вынеся объявление счетчика перед циклом, а его увеличение в конец тела.Интересные факты о работе с циклами
Управляющие команды в теле цикла
Существуют две команды, влияющие на ход выполнения цикла: break, особенности применения которого мы покажем в следующей главе, иcontinue.
- continue: прекращает выполнение тела текущего цикла и осуществляет переход к логическому выражению оператора while. Если вычисленное выражение будет истинно, выполнение цикла будет продолжено.
- break: немедленно прекращает выполнение текущего цикла и осуществляет переход к первой команде за его пределами. Таким образом, выполнение текущего цикла прерывается. Подробнее мы рассмотрим ее в следующей теме.
continue:
while(числоЯблокВТазике>0) {
яблоко = тазик.взятьОчередноеЯблоко();
числоЯблокВТазике--;//-- это декремент, уменьшает количество яблок на единицу
if (яблоко.плохое()) { // метод вернет true для гнилого и т.п. яблока
яблоко.выкинутьВМусор();
continue; // продолжим цикл, перейдем к условию числоЯблокВТазике>0
}
положитьВПирог(яблоко.чистить().нарезать());
}
Конструкцию continue часто применяют, когда в теле цикла необходимо выполнять команды при наступлении некоторого условия, например, выполнить действия при срабатывании датчика в оборудовании (а иначе просто продолжить цикл считывания его показателей) или вычислить выражение только на определенных шагах цикла. Пример для последнего случая: вычисление в цикле while суммы кубов натуральных чисел, у которых квадрат больше их количества. Числа с меньшим квадратом код пропускает через continue:
public static void main(String[] args) {
int sum = 0; // итоговая сумма
int i = 0; // стартовое число ряда
int count = 20; // количество чисел
while(i<=count) {
i++; // берем очередное число, i++ эквивалентно i=i+1
if (i*i<=count) // если квадрат числа меньше
continue; // количества чисел - сумму не считаем
// переходим к следующему числу в цикле
sum += i*i*i; // иначе считаем сумму кубов чисел
} // sum += i*i*i - форма записи, аналогичная sum = sum + i*i*i
System.out.println(sum);// печатаем результат
}
Бесконечный цикл
Данные управляющие команды чаще всего находят применение в бесконечном цикле. Его так называют, потому что логическое условие выхода никогда не выполняется. В коде он выглядит примерно как:
while(true) {
// Тело цикла
}
В этом случае и пригодится применение команды break для организации выхода из него. Этот вид цикла имеет место при ожидании внешних условий, которые формируются за пределами логики тела цикла. Например, в играх, эмулирующих виртуальный мир вокруг героя (выход из цикла = выход из игры), операционных системах. Или при использовании алгоритмов, возможно, улучшающих результат с каждым последующим вызовом в цикле, но ограничивая их по времени или наступлению внешнего события (шашки, шахматы или предсказание погоды). Следует помнить, что в обычных условиях бесконечные циклы это одна из проблем неустойчивости программы.
Для демонстрации вернемся к степеням числа:
public static void main(String[] args) {
int number = 3; // Возводимое в степень число
int result = 1; // Результат возведения в степень
int power = 1; // Начальный показатель степени
while(true) {
result = result * number;
System.out.println(number + " в степени " + power + " = " + result);
power++;
if (power>10)
break; // выход из цикла
}
}
Результат вывода на консоль:
3 в степени 1 = 3
3 в степени 2 = 9
3 в степени 3 = 27
3 в степени 4 = 81
3 в степени 5 = 243
3 в степени 6 = 729
3 в степени 7 = 2187
3 в степени 8 = 6561
3 в степени 9 = 19683
3 в степени 10 = 59049
Process finished with exit code 0
Вложенные циклы
Вот мы и подошли к завершающей теме о наших циклах. Вспомним о яблочном пироге (надеюсь, вы не голодны в данный момент) и наш «цикл»:Если в тазике есть яблоки, выполняем шаги с 1.1 по 1.4:
- 1.1. Берем яблоко
- 1.2. Чистим и нарезаем его дольками
- 1.3. Помещаем на основание пирога из теста на сковороде
- 1.4. Возвращаемся на шаг 1.
- Число долек = 0
Пока число долек < 12, выполнить шаги с 2.1 по 2.3
- 2.1. Отрезать очередную дольку от яблока
- 2.2. Кол-во долек ++
- 2.3. Возвращаемся на шаг 2
Если в тазике есть яблоки, то выполняем шаги с 1.1 по 1.6:
- 1.1. Берем яблоко
- 1.2. Очищаем его от кожуры
- 1.3. Число долек = 0
- 1.4. Пока число долек < 12, выполнить шаги с 1.4.1 по 1.4.3
- 1.4.1. Отрезать очередную дольку от яблока
- 1.4.2. Кол-во долек ++
- 1.4.3. Возвращаемся на шаг 1.4
- 1.5. Помещаем дольки на основание пирога из теста на сковороде
- 1.6. Возвращаемся на шаг 1.

public static void main(String[] args) {
// Выводим значения второго множителя в строке
System.out.println(" 2 3 4 5 6 7 8 9");
int i = 2; // первый множитель, присваиваем стартовое значение
while(i<10) { // Первый цикл, выполняем пока первый множитель меньше 10
System.out.print(i + " | ");// Выводим первый множитель в начало строки
int j = 2; // второй множитель, стартовое значение
while (j<10) { // Второй цикл, выполняем пока второй множитель меньше 10
int mul=i*j; // Считаем произведение множителей
if (mul<10) // Если содержит одну цифру-после него выводим два пробела
System.out.print(mul + " ");
else // иначе выводим произведение и после него - один пробел
System.out.print(mul + " ");
j++; // Увеличиваем на единицу второй множитель,
} // Переходим к началу второго цикла (while (j<10 ).... )
System.out.println(); // Перейдем на следующую строку вывода
i++; // Увеличиваем на единицу первый множитель,
} // Перейдем к началу первого цикла (while ( i<10 ) ....
}
Результат вывода на консоль:
2 3 4 5 6 7 8 9
2 | 4 6 8 10 12 14 16 18
3 | 6 9 12 15 18 21 24 27
4 | 8 12 16 20 24 28 32 36
5 | 10 15 20 25 30 35 40 45
6 | 12 18 24 30 36 42 48 54
7 | 14 21 28 35 42 49 56 63
8 | 16 24 32 40 48 56 64 72
9 | 18 27 36 45 54 63 72 81
Process finished with exit code 0
Циклы (в частности, оператор while) это один из фундаментальных кирпичиков построения программ. Решая задачи на JavaRush, вы изучите все их разнообразие, разберете тонкости функционирования и получите практические навыки их применения.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ