为什么这里不遵循运算符优先级?
Why is the operator precedence not followed here?
在此代码中:
int y = 10;
int z = (++y * (y++ + 5));
如我所愿
由于最里面括号的优先级,第一个y++ + 5
会被执行。所以 y
的值将是 11,这个表达式的值将是 15。然后 ++y * ()
将被执行。所以 12 * 15 = 180。所以 z=180
我得到了什么
z=176
这意味着虚拟机从左到右不遵循运算符优先级。那么我对运算符优先级的理解是错误的吗?
- 第一个会被执行
++y
。 y
将是 11
.
- 然后会执行
y + 5
(其实y++ + 5
可以写成5 + y++
解释为(5 + y)
然后y++
)。 z
会变成 11 * 16 = 176
.
y
计算完成后为12
。
First y++ + 5 will be executed because of the precedence of the innermost parentheses
优先级和求值顺序不是一回事。除赋值表达式外的所有二元表达式都是从左到右求值的。因此 y++
在右边括号表达式之前计算。
计算按顺序进行
z= (++10 * (10++ + 5))
z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
z= (11 * 16)
z= 176
表达式(++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
括号只是描述子表达式将如何组合在一起。括号并不意味着它将首先被评估。相反,java 中的规则是 严格从左到右评估每个子表达式。
永远记住求值顺序与运算符优先级和关联性[=34完全无关=].
Java Oracle 文档说:
15.7. Evaluation Order
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
因此,表达式 (++y * (y++ + 5))
将被计算为
temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16
z = temp1*temp2 = 11*16 = 176
进一步阅读:Eric Lippert's blog, Precedence vs Associativity vs Order, explained in detailed about precedence, associativity and order of evaluation. Though this blog addresses c# but equally valid for java也是。
在此代码中:
int y = 10;
int z = (++y * (y++ + 5));
如我所愿
由于最里面括号的优先级,第一个y++ + 5
会被执行。所以 y
的值将是 11,这个表达式的值将是 15。然后 ++y * ()
将被执行。所以 12 * 15 = 180。所以 z=180
我得到了什么
z=176
这意味着虚拟机从左到右不遵循运算符优先级。那么我对运算符优先级的理解是错误的吗?
- 第一个会被执行
++y
。y
将是11
. - 然后会执行
y + 5
(其实y++ + 5
可以写成5 + y++
解释为(5 + y)
然后y++
)。z
会变成11 * 16 = 176
. y
计算完成后为12
。
First y++ + 5 will be executed because of the precedence of the innermost parentheses
优先级和求值顺序不是一回事。除赋值表达式外的所有二元表达式都是从左到右求值的。因此 y++
在右边括号表达式之前计算。
计算按顺序进行
z= (++10 * (10++ + 5))
z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
z= (11 * 16)
z= 176
表达式(++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
括号只是描述子表达式将如何组合在一起。括号并不意味着它将首先被评估。相反,java 中的规则是 严格从左到右评估每个子表达式。
永远记住求值顺序与运算符优先级和关联性[=34完全无关=].
Java Oracle 文档说:
15.7. Evaluation Order
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
因此,表达式 (++y * (y++ + 5))
将被计算为
temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16
z = temp1*temp2 = 11*16 = 176
进一步阅读:Eric Lippert's blog, Precedence vs Associativity vs Order, explained in detailed about precedence, associativity and order of evaluation. Though this blog addresses c# but equally valid for java也是。