【问题标题】:Java assignment operator behavior vs C++Java 赋值运算符行为与 C++
【发布时间】:2015-12-13 21:32:20
【问题描述】:

这发生在我处理“破解编码面试”问题时:

编写一个函数来就地交换一个数字(即没有临时变量)

我决定用 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 做的事情与其他语言不同?

【问题讨论】:

  • 我认为 (b = a) 在 C++ 中不会返回任何内容。或者我错了,我不懂 C++。
  • @Sweeper b = a 被评估为左值 b,具有赋值的副作用。
  • @Sweeper 作为表达式,它产生分配的值.. 但是,C/C++ 有序列点的“有趣”问题,因此存在未定义的行为。在 Java 中,它是定义的行为,尽管“对我来说太聪明了”。
  • 搜索并阅读序列点(我也推荐this evaluation-order reference)。

标签: java c++ variable-assignment assignment-operator


【解决方案1】:

Java Language Specification, section 15.7 (Evaluation Order)

Java 编程语言保证 运算符似乎以特定的评估顺序进行评估, 即从左到右。

因此,在 Java 中,评估顺序是明确定义的,并且可以满足您的期望。

C++ 规范不提供这样的保证;事实上,它是未定义的行为,所以程序实际上可以做任何事情。

引用cppreference,注意不存在用于对算术运算符进行操作数排序的排序规则:

如果标量对象的副作用相对于某个值是无序的 使用相同标量对象的值进行计算,行为是 未定义。

【讨论】:

  • 相反,“如果标量对象的副作用相对于使用相同标量对象的值的值计算是无序的,则行为未定义。” (cppreference),注意到不存在用于对算术运算符进行操作数排序的排序规则。
猜你喜欢
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 2015-05-02
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 2015-03-19
相关资源
最近更新 更多