Skip to content
Содержание

Ветвления. Циклы

Введение

Управляющие конструкции - это основа любой программы. Они позволяют изменять порядок выполнения инструкций в зависимости от условий (ветвления) и многократно повторять блоки кода (циклы). Без них программа была бы простой последовательностью операторов, выполняемых ровно один раз. В Java существует несколько видов ветвлений и циклов, каждый из которых имеет свои особенности и области применения.

Ветвления

Ветвления позволяют выполнять различные блоки кода в зависимости от истинности некоторого условия. В Java используются:

  • условный оператор if-else;
  • тернарный оператор ?:;
  • оператор множественного выбора (он же switch-case оператор) switch.

if

Синтаксис:

java
if (условие) {
	// Блок кода, выполняемый, если условие истинно
}

Дурацкая запись if-else

Если в блоке только одна инструкция, то фигурные скобки можно опустить. Но так делать - дурной тон. Работать это, конечно, будет, но в приличном обществе такое порицается.

Например:

java
int a = 5;
if (a < 5) {
	System.out.println("a < 5")
}

И также дурацкая (но приемлемая) запись:

java
int a = 5;
if (a < 5) System.out.println("a < 5");
// или
if (a < 5)
	System.out.println("a < 5");

Операторы || и &&

Если необходимо объединить два условия в один if, можно использовать операторы:

  • || - логическое "или";
  • && - логическое "и";

Например - проверить, что число входит в диапазон от 0 до 10 (т.е. число больше нуля И меньше десяти):

java
int a = 5;
if (a > 0 && a < 10) {
	System.out.println("Число принадлежит диапазону (0; 10)");
}

if-else

Когда нужно выполнить одно действие, если условие истинно, и другое - если ложно, используется if-else.

java
if (условие) {
	// если условие истинно
} else {
	// если условие ложно
}

Например:

java
int number = 10;
if (number % 2 == 0) {
	System.out.println("Число чётное");
} else {
	System.out.println("Число нечётное");
}
А кто такой этот ваш number % 2?

% - оператор остатка от деления (или модуло). Конструкция number % 2 == 0 используется для определения чётности/нечётности числа. То есть, если мы возьмём number = 10, и получим остаток от деления на 2, то остатка не будет. Значит число делится на два без остатка, а значит, число чётное. Если же остаток при делении остаётся, значит, число нечётное.

Цепочка if-else if-else

Для проверки нескольких условий последовательно используется конструкция else if.

java
if (условие1) {
	// ...
} else if (условие2) {
	// ...
} else {
	// если ни одно из условий не выполнено
}

Пример:

java
int score = 85; // Балл за экзамен, например 
if (score >= 90) {
    System.out.println("Отлично");
} else if (score >= 75) {
    System.out.println("Хорошо");
} else if (score >= 60) {
    System.out.println("Удовлетворительно");
} else {
    System.out.println("Неудовлетворительно");
}

Тернарный оператор

Пожалуй, самый нечитаемый оператор ветвления. Тернарный оператор - это краткая форма if-else, возвращающая значение. Он удобен для присваивания переменной одного из двух значений в зависимости от условия.

Синтаксис:

java
переменная = условие ? значение_если_истина : значение_если_ложь;

Пример:

java
int a = 5;
int b = 10;
int max = (a > b) ? a : b;
System.out.println("Максимум: " + max);

Ремарка

Тернарный оператор не должен заменять сложные конструкции if-else, если код становится трудночитаемым. Любой тернарный оператор можно заменить простым if-else. Учтите это, чтобы не превратить код в задокументированный приступ шизофазии.

Оператор switch

Оператор switch позволяет выбрать один из множества вариантов выполнения на основе значения выражения (целочисленные типы, char, String, перечисления (потом тут будет ссылка на лекцию о перечислениях)).

Классический синтаксис (до Java 14 (которую мы не используем, но для общего развития))

java
switch (выражение) {
	case значение1:
		// операторы
		break;
	case значение2:
		// операторы
		break;
		
	default:
		// операторы, если ни один case не совпал
}

Пример:

java
int dayOfWeek = 3;
switch (dayOfWeek) {
    case 1:
        System.out.println("Понедельник");
        break;
    case 2:
        System.out.println("Вторник");
        break;
    case 3:
        System.out.println("Среда");
        break;
    default:
        System.out.println("Неизвестный день");
}

оператор break

без оператора break выполнение «проваливается» в следующий блок case, что может приводить к ошибкам. Иногда это используется намеренно, но чаще требуется break.

Современный синтаксис (Java 14+)

Начиная с Java 14, switch может использоваться как выражение и поддерживает стрелочную форму, что исключает «проваливание» и необходимость break.

java
int dayOfWeek = 3;
String dayName = switch (dayOfWeek) {
    case 1 -> "Понедельник";
    case 2 -> "Вторник";
    case 3 -> "Среда";
    default -> "Неизвестный день";
};
System.out.println(dayName);

Также можно использовать блоки с yield для возврата значения:

java
int num = 2;
String result = switch (num) {
    case 1 -> "Один";
    case 2 -> {
        String s = "Два";
        yield s.toUpperCase(); // возвращает "ДВА"
    }
    default -> "Другое";
};

Ремарка

switch-case используется не то чтобы часто. Его всегда можно заменить цепочкой if-else. Поэтому, использовать его или нет - на ваше усмотрение (я им не пользуюсь примерно никогда. Вообще.).

Циклы

Циклы позволяют многократно выполнять один и тот же блок кода, пока выполняется условие. В Java есть четыре вида циклов:

  • while - цикл с предусловием;
  • do-while - цикл с постусловием;
  • for - цикл со счётчиком;
  • расширенный for (он же for-each, он же питоновский for) - для перебора элементов.

Цикл while

Ситнаксис:

java
while (условие) {
	// тело цикла (что делаем)
}

while является циклом с предусловием. То есть, условие проверяется перед каждым выполнением тела. Если условие изначально ложно, тело не выполнится ни разу.

Пример - вывод чисел от 1 до 5:

java
int i = 1;
while (i <= 5) {
	System.out.println(i);
	i++;
}

Истинность условия

Если условие цикла никогда не станет ложным, цикл станет бесконечным!

Цикл do-while

Отличается от while тем, что условие проверяется после выполнения тела, поэтому тело выполнится как минимум один раз.

Синтаксис:

java
do {
	// тело цикла
} while (условие);

Пример - запрос ввода, пока не будет введено положительное число:

java
Scanner scanner = new Scanner(System.in); // не забываем про импорт 
int number;
do {
    System.out.print("Введите положительное число: ");
    number = scanner.nextInt();
} while (number <= 0);
System.out.println("Вы ввели: " + number);

Цикл for

Цикл for удобен, когда заранее известно количество итераций или есть явный счётчик. Синтаксис:

java
for (инициализация; условие; обновление) {
    // тело цикла
}
  • Инициализация выполняется один раз перед началом цикла.
  • Условие проверяется перед каждой итерацией; если оно ложно, цикл завершается.
  • Обновление выполняется после каждой итерации.

Пример - вывод чисел от 0 до 4:

java
for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

TIP

Все три части необязательны, в отличие от точки с запятой. То есть запись вида for (;;) - абсолютно легальна. Такое использование for эквивалентно while (true) (и то, и то - бесконечные циклы). Но! В ситуации, когда вам нужен бесконечный цикл, использование while (true) предпочтительнее.

Цикл for-each

Используется для перебора элементов массива или коллекции без явного индекса.

Синтаксис:

java
for (тип переменная : коллекция_или_массив) {
    // тело цикла, переменная принимает значение текущего элемента
}

Пример - сумма элементов массива:

java
int[] numbers = {1, 2, 3, 4, 5}; // это массив. Их мы пройдём позже
int sum = 0;
for (int num : numbers) {
    sum += num;
}
System.out.println("Сумма: " + sum);

Особенности:

  • Нельзя изменять сам массив (добавлять/удалять элементы) во время итерации.
  • Не подходит, если нужен индекс элемента (тогда используйте обычный for).

Главное правило циклов

Если количество итераций неизвестно - используйте while/do-while. Если же известно - for.

Операторы break и continue

Эти операторы управляют выполнением цикла:

  • break - немедленно завершает цикл (или switch).
  • continue - пропускает оставшуюся часть текущей итерации и переходит к следующей.

Пример break - поиск элемента:

java
int[] array = {1, 5, 8, 3, 9};
int target = 3;
boolean found = false;
for (int i = 0; i < array.length; i++) {
    if (array[i] == target) {
        found = true;
        break; // выходим из цикла
    }
}
System.out.println(found ? "Найден" : "Не найден");

Пример continue - вывод только чётных чисел:

java
for (int i = 1; i <= 10; i++) {
    if (i % 2 != 0) {
        continue; // пропускаем нечётные
    }
    System.out.println(i);
}

Практическая работа №2

1. Чётное или нечётное

Напишите программу, которая запрашивает у пользователя целое число и выводит сообщение: "число чётное" или "число нечётное"

2. Сумма чисел от 1 до N

С клавиатуры вводится целое положительное число N. Вычислите сумму всех целых чисел от 1 до N включительно (если N = 5, то сумма должна быть равна 1 + 2 + 3 + 4 + 5) и выведите результат. Предусмотрите ситуацию, в которой пользователь вводит отрицательное число или ноль.

3. Таблица умножения

Выведите на экран таблицу умножения для числа, введённого пользователем (от 1 до 9). Формат вывода (на ввод дано 5):

5 x 1 = 5
5 x 2 = 10
...
5 x 9 = 45

Предусмотреть неправильный ввод пользователем.

4*. Дополнительное задание. Угадай число

Напишите программу, которая загадывает случайное целое число от 1 до 100 (включительно). Пользователь должен угадать это число не более чем за 7 попыток. После каждой попытки программа выводит одну из подсказок:

  • «Загаданное число больше»
  • «Загаданное число меньше»
  • «Поздравляем! Вы угадали число X с N-й попытки!» (если угадал)

Если попытки закончились, а число не угадано, программа выводит сообщение:
«Вы проиграли. Загаданное число было: X».

Подсказка - случайные числа в диапазоне:

java
import java.util.Random;
// ...
Random random = new Random(); // создаём генератор случайных чисел
int min = 1; // указываем нижнюю границу диапазона
int max = 100; // верхняя граница диапазона
int randomNumber = random.nextInt(max - min + 1) + min; // число от min до max включительно