Почему в этом случае приоритет оператора не соблюдается?
В этом коде:
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 говорит, что:
Язык программирования Java гарантирует, что операнды операторов, по-видимому, оцениваются в определенном порядке оценки, а именно слева направо.
Следовательно, выражение (++y * (y++ + 5))
будет оцениваться как
temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16
z = temp1*temp2 = 11*16 = 176
Дальше: блог Эрика Липперта, Приоритет против ассоциативности и порядка, подробно объяснил, как приоритет, ассоциативность и порядок оценки. Хотя этот блог адресован С#, но в равной степени применимо для java тоже.
Ответ 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