Почему в этом случае приоритет оператора не соблюдается?

В этом коде:

int y = 10;
int z = (++y * (y++ + 5)); 

Что я ожидал

Первый y++ + 5 будет выполнен из-за приоритета самых внутренних скобок. Таким образом, значение y будет равно 11, а значение этого выражения будет равно 15. Тогда будет выполняться ++y * (). Итак, 12 * 15 = 180. Итак, z = 180

Что я получил

г = 176

Это означает, что виртуальная машина движется слева направо, не следуя приоритету оператора. Так неправильно ли мое понимание приоритета оператора?

Ответы

Ответ 1

Выражение (++ y * (y ++ + 5)); будет помещен в стек примерно так:

1. [++y]
2. [operation: *]
3. [y++ + 5] // grouped because of the parenthesis

И он будет выполнен в этом порядке, как результат

1. 10+1 = [11] // y incremented 
2. [operation: *]
3. 11+5 = [16] // y will only increment after this operation

Выражение оценивается как

11 * 16 = 176

Ответ 2

Первый y ++ + 5 будет выполнен из-за приоритета самых внутренних скобок

Приоритет и порядок оценки - это не одно и то же. Все двоичные выражения, кроме выражения присваивания, оцениваются слева направо. Поэтому y++ оценивается перед заключенным в скобки выражением справа.

Ответ 3

В скобках просто описывается, как подвыражения будут группироваться вместе. Parenthesizing не означает, что он будет оценен первым. Скорее, правило в java оценивает каждое подвыражение строго слева направо.

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

Документация Java Oracle говорит, что:

15.7. Порядок оценки

Язык программирования Java гарантирует, что операнды операторов, по-видимому, оцениваются в определенном порядке оценки, а именно слева направо.

Следовательно, выражение (++y * (y++ + 5)) будет оцениваться как

temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16 
z = temp1*temp2 = 11*16 = 176  

Дальше: блог Эрика Липперта, Приоритет против ассоциативности и порядка, подробно объяснил, как приоритет, ассоциативность и порядок оценки. Хотя этот блог адресован , но в равной степени применимо для тоже.

Ответ 4

  • Сначала будет выполнен ++y. y будет 11.
  • Затем будет выполнен y + 5 (фактически y++ + 5 может быть записан как 5 + y++, который интерпретируется как (5 + y), а затем y++). z станет 11 * 16 = 176.
  • y будет 12 после завершения вычисления.

Ответ 5

Расчет выполняется следующим образом

 z= (++10 * (10++ + 5))
 z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
 z= (11 * 16)
 z= 176