В предыдущих уроках мы уже сталкивались с вопросом приоритета операций, но особо не акцентировали внимание на этом вопросе. Мы обходились тем, что с помощью скобок явно указывали приоритет, остальное умолчали. Пришло время восполнить пробел и расставить все точки над i.
Вернемся к школьной математике. Простой пример.
1 + 2 * 3
Чему равно значение этого выражения? Если бы мы выполняли операции просто слева направо, то сначала выполнили бы первую операцию - сложение 1 + 2, получили бы 3. Затем выполнили бы вторую операцию - умножение 3 * 3, и в итоге получили бы 9. Но нет! В математике есть приоритет операций. Сначала мы должны выполнить операцию умножения 2 * 3, получить 6, а затем выполнить операцию сложения 1 + 6 и получить в итоге 7.
Если бы мы хотели сначала выполнить операцию сложения, а затем операцию умножения, то мы могли бы задать вручную приоритет операции сложения - при помощи скобок.
(1 + 2) * 3
В таком случае сначала выполнится сложение 1 + 2, а затем умножение и результат выражения будет равен 9.
В Java принципы работают аналогично. Только операций гораздо больше.
Чему например будет равно значение выражения?
2 != 3 || 5 > 7 && 3 == 2 + 1 ? 2 + 5 : 4 * 8
Без знания того, в каком порядке в этом выражении будут выполняться операции, ответить на этот вопрос сложно.
Поэтому очень важно при написании кода следить за приоритетом операций.
Итак, в порядке убывания приоритета.
1. () круглые скобки.
С помощью них можно явно задать, в каком порядке должны быть выполнены операции. Причём если одни скобки выложены в другие, сначала выполнятся операции во вложенных скобках, а затем во внешних.
Например,
( (1+1) * (2+2) ) / (1+3)
Сначала выполнятся операции во вложенных скобках (1+1) = 2 и (2+2) = 4, затем выполнятся операции во внешних скобках 2 * 4 = 8 и (1+3) = 4. В третью очередь выполнится операция вне скобок 8 / 4 = 2.
2. Инкремент ++, декремент --, логическое НЕ !
3. Умножение *, деление /, остаток от деления %
4. Сложение +, вычитание -
5. Больше >, больше или равно >=, меньше <, меньше или равно <=
6. Равно ==, не равно !=
7. Логическое И &&
8. Логическое ИЛИ ||
9. Тернарный оператор ? :
10. Операторы присваивания =, +=, -=, *=, /=, %=
Ещё раз акцентирую внимание. Операторы расположены в порядке убывания приоритета. У скобок максимальный приоритет. У операторов присваивания - минимальный (они выполнятся в последнюю очередь).
Это не все возможные операторы. Есть и другие, в частности, побитовые операторы, которые также необходимо включить в список. Но мы их не рассматривали и на данный момент включать их в список я намеренно не буду. Мы сделаем это позже.
Ещё один важный момент, на котором я акцентирую внимание. Все операторы, указанные в пунктах с 1 по 9, при одинаковом приоритете выполняются слева направо.
Например.
9 % 4 * 2
У операций остатка от деления и умножения одинаковый приоритет. В каком порядке они выполнятся?
Сначала выполнится тот оператор, который расположен левее.
9 % 4 равно 1.
Затем 1 * 2 равно 2.
Операторы присваивания, указанные в пункте 10, выполняются в порядке справа налево.
В этом уроке не буду придумывать задачу и расписывать решение. Давайте лучше разберём выражение, которое ранее было написано:
2 != 3 || 5 > 7 && 3 == 2 + 1 ? 2 + 5 : 4 * 8
Как же посчитать его значение?
Давайте обратимся к приоритету операций.
Самая приоритетная операция в этом выражении - умножение. Давайте её выполним и пойдём дальше. Перемножили 4 и 8, получили 32. Переписываем выражение
2 != 3 || 5 > 7 && 3 == 2 + 1 ? 2 + 5 : 32
Следующая по приоритету у нас операция сложения. Выполним все сложения. 2 + 1 равно 3, 2 + 5 равно 7. Опять переписываем.
2 != 3 || 5 > 7 && 3 == 3 ? 7 : 32
Ага. Уже проще. Следующая по приоритету у нас операция сравнения: >
5 > 7. Это правда? Нет. Переписываем в очередной раз
2 != 3 || false && 3 == 3 ? 7 : 32
Следующие по приоритету операции сравнения равно == и не равно !=
2 не равно 3. Это правда? Да. Значит, это выражение примет значение true.
3 равно 3. Это правда? Да. Значит, это выражение тоже примет значение true.
Переписываем
true || false && true ? 7 : 32
Далее по приоритету логическое И &&
Ложь и правда (true и false) - это правда? Нет, это ложь. Значит, значение всего этого выражения ложь, т.е. false.
Получаем
true || false ? 7 : 32
Дальше по приоритету логическое ИЛИ ||
true || false. Правда или ложь? Какое значение в итоге? Правильно - true.
true ? 7 : 32
С самым низким приоритетом в исходном выражении у нас тернарный оператор. Мы помним, как он работает.
Если значение до знака вопроса true, то он принимает значение, расположенное между знаком вопроса и двоеточием.
Таким образом, значение всего выражения
2 != 3 || 5 > 7 && 3 == 2 + 1 ? 2 + 5 : 4 * 8
будет равно 7.
Если у Вас есть желание Вы можете вывести значение этого выражения на экран с помощью оператора вывода текста. Вы с ним давно знакомы и сами сможете написать весь код программы для вывода. Я напишу только сам оператор вывода текста
System.out.println( 2 != 3 || 5 > 7 && 3 == 2 + 1 ? 2 + 5 : 4 * 8 );
Выводы из урока:
- При написании кода очень важно контролировать приоритет операций в сложных выражениях
- Все операторы, про которые шла речь в текущем уроке, кроме операторов присвоения, выполняются в порядке слева направо. Операторы присвоения - наоборот. Сначала выполняются те, которые расположены правее и затем по порядку влево.
Ссылка на предыдущий урок
Ссылка на следующий урок
Ссылка на содержание курса