Введение
Наши самые первые программы представляли собой последовательность инструкций, которые выполняются одна за другой. Без развилок. Это и HelloWorld, выводящий в консоль фразу приветствия, арифметические вычисления. После первых программ мы научились ветвлению, то есть программа выполняла те или иные действия в зависимости от условий. Вот как можно было бы закодировать включение кондиционера на обогрев и охлаждение:if (tempRoom>tempComfort)
airConditionerOn();
if (tempRoom<tempComfort
heaterOn();
Сделаем следующий шаг. В быту мы часто выполняем однообразные повторяющиеся действия, например, чистим яблоки для пирога. Этот увлекательный процесс можно описать как:
Если в тазике есть яблоки, то выполняем шаги с 1.1 по 1.4:
- 1.1. Берём яблоко
- 1.2. Чистим и нарезаем его дольками
- 1.3. Помещаем на основание пирога из теста на сковороде
- 1.4. Возвращаемся на шаг 1.
Допустим у вас 10 яблок, 2 руки и один нож. В жизни вы последовательно чистите весь десяток, руководствуясь одним и тем же алгоритмом. А как заставить программу делать повторяющееся действие с каждым яблоком?
- Привяжем себя к числу яблок,но если у нас их мало – часть команд выполнялось бы вхолостую без «полезной нагрузки» (и, возможно, порезались, очищая кожуру несуществующего яблока).
- Если яблок больше, чем наших команд обработки – часть продуктов пропала бы необработанной.
- Подобный «код» тяжело читать, в нём много повторов, его трудно модифицировать.
Циклы – операторы многократного выполнения действий
Цикл while Java (цикл вайл) хорошо подойдёт в нашем случае. Эта конструкция оформляет многократные действия в лаконичную и понятную структуру. Алгоритм по нарезке яблок для пирога в виде while в Java мог бы выглядеть как:while(числоЯблокВТазике>0) {
яблоко = тазик.взятьОчередноеЯблоко();
положитьВПирог(яблоко.чистить().нарезать());
числоЯблокВТазике--;//-- это декремент, уменьшает количество яблок на единицу
}
System.out.println('Яблоки для пирога обработаны.');
Синтаксис команды
Первый способ описания оператора while следующий:while(Логическое выражение) {
// Тело цикла - периодически выполняемые оператор(ы)
}
Выполняется следующим образом (по шагам):
- Вычисляем Логическое условие, следующее в скобках за while.
- Если логическое условие истинно, то выполняются операторы в теле цикла, после выполнения последнего оператора в теле цикла, переходим на шаг 1
- Если логическое условие ложно, то переходим к первому оператору за пределами цикла while.
Цикл с предусловием
Так как перед выполнением тела цикла мы всегда предварительно вычисляем логическое выражение (условие входа в цикл), то этот вид while часто называют циклом с предусловием. Построим таблицу первых десяти целых, положительных степеней числа: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
Обратите внимания на изменения в коде, сравнив с вариантом цикла с предусловием.
Интересные факты о работе с циклами
Управляющие команды в теле цикла
Существуют две команды, влияющие на ход выполнения цикла: break, особенности применения которого мы покажем в следующей главе, и- continue – прекращает выполнение тела текущего цикла и осуществляет переход к логическому выражению оператора while. Если вычисленное выражение будет истинно – выполнение цикла будет продолжено.
- break – немедленно прекращает выполнение текущего цикла и осуществляет переход к первой команде за его пределами. Таким образом, выполнение текущего цикла прерывается. Подробнее мы рассмотрим её в следующей теме.
continue
:
while(числоЯблокВТазике>0) {
яблоко = тазик.взятьОчередноеЯблоко();
числоЯблокВТазике--;//-- это декремент, уменьшает количество яблок на единицу
if (яблоко.плохое()) { // метод вернет true для гнилого и т.п. яблока
яблоко.выкинутьВМусор();
continue; // продолжим цикл, перейдем к условию числоЯблокВТазике>0
}
положитьВПирог(яблоко.чистить().нарезать());
}
Конструкцию continue
часто применяют, когда в теле цикла необходимо выполнять команды при наступлении некоторого условия, например, выполнить действия при срабатывании датчика в оборудовании (а иначе просто продолжить цикл считывания его показателей) или вычислить выражение только на определенных шагах цикла. Пример для последнего случая – вычисление в цикле while суммы кубов натуральных чисел, у которых квадрат меньше их количества:
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, вы изучите все их разнообразие, разберёте тонкости функционирования и получите практические навыки их применения.