【问题标题】:Unary operators in java vs c++ [duplicate]java vs c ++中的一元运算符[重复]
【发布时间】:2012-07-03 12:41:39
【问题描述】:

可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
Is there any difference between the Java and C++ operators?

为什么一元运算符在 c++ 和 java 中给出不同的结果?

看看这个:

int i = 1;
i = i++ + ++i;
print i  (with cout or println)

java 中:打印 4

c++ 中:打印 5

为什么?

【问题讨论】:

  • 这会在 Java 中为我打印 4
  • 这是undefined behaviour。有很多很多帖子。快速搜索建议从stackoverflow.com/questions/4176328/…stackoverflow.com/questions/4638364/… 开始。另请注意,我使用 g++ 得到 5
  • @Keppil 谢谢,但实际上,我不确定引用的评论是否正确,所以删除了我的。
  • 耶!对不起@Keppil。版画变了。对不起:-P

标签: java c++ unary-operator


【解决方案1】:

在 C++ 中,i = i++ + ++i; 等语句的行为实际上是未定义,因此行为不同这一事实并不令人惊讶。

事实上,如果两个不同的 C++ 编译器为 C++ 语句 i = i++ + ++i; 产生不同的行为,这不足为奇。

相关问题:

【讨论】:

  • Java 实际上 指定了这个表达式的值,C++ 把它留给编译器。
  • C++ 实际上把它留给了硬件。 Java 没有这个问题,它只在 JVM 上运行。
  • @BoPersson:不过,我认为这与硬件无关。
  • @nhahtdh - 但我愿意。我已经看到对内存总线将锁定同时读取和写入同一地址的系统的引用。这就是为什么它是未定义的,而不仅仅是未指定的。
  • 一些 情况下,我确信编译器会将其留给硬件。无论这是否是语言创造者选择将其定义为 undefined 的原因,除了他们自己之外没有人知道。
【解决方案2】:

用这段代码更好地解释:

int i = 1;
int j =0;
j = i++ + ++i;
print j  (with cout or println)

在 java 中 i++ 和 ++i 有相同的结果 i 增加 1 所以你这样做:2 + 3 = 5 之后我将 5 岁。 j 之后会是 5

在 c++ 中,i++ 和 ++i 的行为不同 i++ 原地递增,而 ++i 之后递增。

所以它读作 2+ 2。 j 将是 4,我将是 5。

【讨论】:

  • 你对 Java 的理解是错误的,它是 1 + 3 而不是 2 +3,因此结果是 4 而不是 5。
【解决方案3】:

C++ 和 Java 是不同的语言,所以有不同的效果。查看运营商优先级。

在 Java 中++(后缀和前缀)在同一行,而在 C++ 中它们具有不同的优先级。

【讨论】:

    【解决方案4】:

    在 Java 中,后修复增量 ++ 运算符有点“原子”(与线程无关),因为值被计算到表达式中,并且增量发生时不受其他运算符的干扰。

    Operator precedence table 来自维基百科的 Java。

    i = i++ + ++i
    i = ((i++) + (++i))
    i = (1 + (++i)) // i = 2
    i = (1 + 3) // i = 3
    i = 4
    

    对于 C,行为未按标准定义。

    Operator precedence 来自维基百科的 C。

    【讨论】:

      【解决方案5】:
      i = i++ + ++i;
      

      导致未指定的行为,这意味着您可以使用不同的编译器或不同的编译器设置获得不同的结果。

      【讨论】:

      • 我相信它是未定义的,而不是未指定的。未指定意味着编译器必须选择一些东西并始终如一地做。未定义意味着你自己...
      • @BoBTFish,不,Standart 说“1.3.13 未指定行为 [defns.unspecified] 行为,对于格式良好的程序构造和正确的数据,这取决于实现。实现不是需要记录发生的行为。”。另一方面,未定义行为是“1.3.12 未定义行为 [defns.undefined] 行为,例如在使用错误程序构造或错误数据时可能出现的行为,本国际标准对此没有任何要求。”。行 i = i++ + ++i;是一个正确的程序,所以它是未指定的行为。
      • 我没有引用标准,但引用 Bjarne 是一个好的开始:Basically, in C and C++, if you read a variable twice in an expression where you also write it, the result is undefined.www2.research.att.com/~bs/bs_faq2.html#evaluation-order
      • @BoBTFish,我认为我们这里的术语有些含糊不清。我坚信“如果你在一个表达式中读取一个变量两次,结果是未定义的”这句话意味着开发人员的结果是未定义的。我发布的标准引用中提到了编译器,这意味着 标准 未为 compilers 指定未指定的行为。所以我认为我们在这里只是从不同的角度谈论同一件事。
      • 我想我找到了我想要的。这是 C++11 最终草案 (N3092),因此部分编号可能已更改。部分1.9.15Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced... If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined... i = v[i++]; // the behavior is undefined
      【解决方案6】:
      int i = 1;
      i = i++ + ++i;
      System.out.println(i);
      
      int i = 1;
      int j = i++ + ++i;
      System.out.println(j);
      

      总是给出 4,因为在 Java 中 parse expression 从左到右 (LALR)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-14
        • 1970-01-01
        • 2014-01-16
        • 1970-01-01
        • 2014-09-29
        • 2013-10-16
        • 2015-04-04
        • 1970-01-01
        相关资源
        最近更新 更多