Найти тему

Крутой курс Java для "чайников". Урок 14. Приоритет операций.

В предыдущих уроках мы уже сталкивались с вопросом приоритета операций, но особо не акцентировали внимание на этом вопросе. Мы обходились тем, что с помощью скобок явно указывали приоритет, остальное умолчали. Пришло время восполнить пробел и расставить все точки над 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 );

Выводы из урока:

  • При написании кода очень важно контролировать приоритет операций в сложных выражениях
  • Все операторы, про которые шла речь в текущем уроке, кроме операторов присвоения, выполняются в порядке слева направо. Операторы присвоения - наоборот. Сначала выполняются те, которые расположены правее и затем по порядку влево.

Ссылка на предыдущий урок

Ссылка на следующий урок

Ссылка на содержание курса