【问题标题】:Operator precedence in JavaJava中的运算符优先级
【发布时间】:2011-12-28 01:45:35
【问题描述】:

http://leepoint.net/notes-java/data/expressions/precedence.html 的一个例子

下面的表达式

1 + 2 - 3 * 4 / 5

被评估为

1 + 2 - 3 * 4 / 5
    = (1 + 2) - ((3 * 4) / 5)
    = 3 - (12/5)
    = 3 - 2 The result of the integer division, 12/5, is 2 .
    = 1

然后我看到http://www.roseindia.net/java/master-java/operator-precedence.shtml的另一个例子

下面的表达式

4 + 5 * 6 / 3

被评估为

4 + (5 * (6 / 3))

当涉及 * 和 / 时,我对如何决定首先评估哪个感到有些困惑。在上面的示例中,两者似乎有所不同。

第一个示例将3*5/5 评估为((3*4)/5) 而第二个例子是评估5*6/3 as (5*(6/3))

我知道 * 和 / 优先于 + 和 - 但是当表达式同时包含 * 和 / 时呢?还有为什么上面两个例子显示了不同的方法?其中一个是错的吗?

编辑

public class ZiggyTest {  

    public static void main(String[] args) {  
            System.out.println(4 + (5 * (6 / 3)));
            System.out.println(4 + ((5 * 6) / 3));

            System.out.println(1 + 2 - (3 * (4 / 5)));  
            System.out.println(1 + 2 - ((3 * 4) / 5));  
    }  
 } 

上面的程序产生输出

14
14
3
1

如果第一个产生相同的输出,为什么最后两个输出不一样。

【问题讨论】:

  • 我怀疑 4 + 5 * 6 / 3 被评估为 4 + (5 * (6 / 3)) 它只是在正确评估时给出相同的结果 (4 + ( ( 5 * 6 ) / 3 ))。

标签: java operators scjp


【解决方案1】:

当涉及到 * 和 / 时,我对如何决定首先评估哪个感到有点困惑

这就是我们有规范的原因:)

Section 15.7 是 Java 语言规范中处理评估顺序的部分,section 15.17 声明:

运算符 *、/ 和 % 称为乘法运算符。它们具有相同的优先级并且在语法上是左结合的(它们从左到右分组)。

所以只要有A op1 B op2 C 并且op1op2 都是*/%,它就相当于

(A op1 B) op2 C

或者换一种说法——第二个链接的文章在他们的例子中是完全错误的。这是一个证明它的例子:

int x = Integer.MAX_VALUE / 2;        
System.out.println(x * 3 / 3);
System.out.println((x * 3) / 3);
System.out.println(x * (3 / 3));

输出:

-357913942
-357913942
1073741823

这表明乘法发生在首先(导致整数溢出)而不是除法(最终会乘以 1)。

【讨论】:

【解决方案2】:

你确定吗?

4 + (5 * 6) / 3
4 + 30 / 3
4 + 10
14

4 + 5 * (6 / 3)
4 + 5 * 2
4 + 10
14

它们产生相同的输出,因为添加括号不会改变结果。对于您的其他方程式,括号实际上确实会改变结果。通过删除我求解的方程中的括号,结果的正确路径是第一个。

【讨论】:

    【解决方案3】:

    第二个是错的。请参阅Jon Skeet's 答案。乘法运算符从左到右求值。分组:

    4 + 5 * 6 / 3
    

    应该是

    4 + ((5 * 6) / 3).
    

    但是,在这种情况下,错误的分组

    4 + (5 * (6 / 3))
    

    给出相同的答案。

    【讨论】:

    • 啊,是的,我明白了。碰巧两个分组产生相同的结果。谢谢
    猜你喜欢
    • 2012-12-13
    • 2021-10-25
    • 2015-08-29
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多