Почему такой приоритет операций в Java

int number = 2;
System.out.println(number + number * (number + ++number));
System.out.println(number);

Почему на экран будет выведено 12, а не 18. Немного не понимаю, number же увеличивается в скобках. Почему еще у унарных операторов ассоциативность справа налево? Как это работает?


Ответы (1 шт):

Автор решения: Roman Konoval

Есть три вещи, которые важно не путать:

  1. приоритет операций
  2. ассоциативность операций
  3. порядок вычисления подвыражений

Рассмотрим на примере выражения a / b / c - d.

Приоритет и ассоциативность задают правила расстановок скобок в выражении. Т.е. приоритет операций нам говорит, что a / b / c - d == (a / b / c) - d. Ассоциативность - что (a / b / c) - d == ((a / b) / c) - d.

Обратите внимание, что правила ассоциативности и приоритета ничего не говорят нам о том, в каком порядке нужно вычислять подвыражения a, b, c и d. Они говорят только о том, в каком порядке нужно выполнять операции над операндами, но не о порядке вычисления операндов.

А об этом говорит правило порядка вычисления подвыражений:

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

Весь ваш вопрос и замешательство связаны как раз с порядком вычисления подвыражений.

Для выражения number + number * (number + ++number) порядок вычислений подвыражений будет таким:

number + number * (number + ++number)
 ^         ^         ^          ^
 |         |         |          |
 1         2         3          4       -  порядок вычисления

 2     +   2    * (  2    +     3   )   ==   12   

Теперь, что касается a = 3; b = ++a + (a-- * ++a);. Тут к написанному выше еще добавляется правило, что пре-(пост-) ин(де)кремент модифицирует переменную до(после) вычисления подвыражения.

a = 3;
b = ++a + (a-- * ++a);
      ^    ^       ^ 
      1    2       3        порядок вычисления подвыражений
                      
      4 + (4   *   4)       значение подвыражения
      4    3       4        значение а после вычисления подвыражения

Так что в результате будет 4 * (4 + 4).

Почему еще у унарных операторов ассоциативность справа налево? Как это работает?

В выражениях типа ++ ++ a и - - 2 скобки согласно ассоциативности расставляются так (++ (++ a)) и (- (- 2)), что ожидаемо и естественно, т.к. мы не можем применять оператор до того, как рассчитаем его аргумент.

→ Ссылка