Java赋值运算符行为与C++的区别

5

当我尝试解决《破解编程面试》中的一个问题时,发生了这种情况:

写一个函数,在不使用临时变量的情况下交换两个数

我决定用Java编写我的解决方案(因为我计划在实习面试中使用Java)。

我想出了一个解决方案,我几乎有信心它是正确答案(因为我只用了一行代码):

    public static void main(String args[]) {
        int a = 5;
        int b = 7;
        a = b - a + (b = a);
        System.out.println("a: " + a + " b: " + b);
    }

毫无疑问,这段代码执行了期望的结果。a == 7b == 5

现在有趣的部分来了。

这段代码在C++中不会运行,在书后也没有这个解决方案。

所以我的问题是:为什么我的解决方案有效?我假设Java与其他语言的处理方式不同?


1
我认为在C++中 (b = a) 不会返回任何东西。或者也许我错了,我不懂C++。 - Sweeper
1
对于Java:https://dev59.com/questions/fmcs5IYBdhLWcg3wcTgz - user180100
1
@Sweeper b = a 的求值结果是一个左值 b,并带有赋值的副作用。 - user2486888
2
@Sweeper 作为一个表达式,它会产生被赋值的值...然而,C/C++ 存在序列点的“有趣”问题,因此会导致未定义行为。在 Java 中,这是已定义的行为,尽管对我来说有些“过于聪明”。 - user2864740
1
搜索并阅读关于“序列点”的内容(我还推荐这个求值顺序参考)。 - Some programmer dude
显示剩余4条评论
1个回答

5
请看Java语言规范第15.7节(评估顺序)
Java编程语言保证运算符的操作数按照特定的评估顺序从左到右进行评估。
因此,在Java中,评估顺序是明确定义的,其行为与您期望的相同。
C++规范没有提供这样的保证;事实上,它是未定义的行为,因此程序可能会做任何事情。
引用cppreference的说法,注意到算术运算符的操作数不存在排序规则:
如果标量对象的副作用对值计算使用同一标量对象的值不具有排序,那么其行为未定义。

2
相反,"如果标量对象上的副作用相对于使用相同标量对象的值计算是无序的,则行为未定义"(cppreference),需要注意的是,不存在对算术运算符操作数进行排序的排序规则。 - Amadan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接