java - 谁能解释为什么C和Java中的输出不同?

原文 标签 java c++ c

{
 public static void main(String[] args) {
     int a = 10;
     if (a == a--)
     System.out.println("first\t");
     
     a=10;
     if(a==--a)
     System.out.println("second\t");
     
 }
}
对于Java程序,输出为“第一”,而对于C/C++程序,其输出为“第二”。据我所知,这两个程序中的后修复/修复操作功能相同。如果有人可以对逻辑有所了解,那将是一件很棒的事情,因为我是编码新手。

int main()
{
   int a = 10;
   if(a==a--)
   
       printf("first\t");
   
   a=10;
   if(a==--a)
   
       printf("second\t");
   
}

最佳答案

在Java中,您可以保证始终观察到此代码,输出First,而从不Second.在C/C++中,您无法获得任何保证。根据编译器,体系结构,操作系统和月相的不同,它可能只会打印FirstSecond,但是我很确定C和C++规范使其成为“合法”的编译器/体系结构/OS/阶段-moon组合键最终同时打印FirstSecond甚至都不打印。
请参阅C++的order of evaluation规则:给定一些二进制运算符构造:a x b其中a和b是表达式,x是一些二进制运算符,然后必须首先评估ab,然后将x运算符应用于如此获得的值。除非运算符明确地降低顺序(例如||&&运算符会这样做;否则他们 promise 会短路,即如果b这样的b不能影响结果,则根本不评估a)-那么C(++)编译器可以自由发出代码,以便在b之前先评估a,反之亦然。
C充满了“应该”和“可能”的边界:C规范旨在允许C代码在各种各样的芯片上进行编译,并具有大量的余地,以使编译器可以应用深远的优化。到目前为止,简单的原始数据类型具有未指定的位宽。
与Java相比,几乎所有内容都被锁定:Java代码中很少有一些方面是故意未指定的,并且编译器处于“正常运行”状态,并且在允许发出的字节码方面非常有限(在Java中,优化将留给运行时/热点编译器,而不是javac)。
这就是为什么在Java上规范明确定义了a x b应该如何解析的原因:java规范确实规定,无论运算符如何,必须始终在评估a之前对b进行评估(除非像在C中那样,b不是根据短路规则进行评估)。
一直追溯到Java语言规范v7 the spec explicitly dictates the left hand side MUST be evaluated first,此后就没有改变(而且我很确定自Java 1.0以来的确如此,因为它的值(value)。在大多数JLS版本中可能是第15.7.1章)。

相关文章:

c++ - 从文件中读取大量数据并以有效的方式解析日期。如何提高海量数据的性能?

c - 带数组指针的for循环,将值设置为指针

java - java.lang.ClassCastException为什么?

java - 查找与列表中的模式匹配的内容的快速方法

java - Logback日志记录-同步或异步

c++ - 是否有将范围移动到 vector 的标准方法?

c++ - boost ,共享内存和 vector

c++ - 调用glBindVertexArray(vao):如果 'vao'已绑定(bind),该怎么办?如何设计形状类?

c - 使用C解析JSON

java - Android:管理多个通知