{
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++ 中,您没有这样的保证。根据编译器、体系结构、操作系统和月相,它可能只打印 First
或 Second
但我很确定 C 和 C++ 规范可以做到编译器/架构/操作系统/月球相位组合的“合法”最终打印 First
和 Second
或什至都不打印。
见 order of evaluation C++ 规则:给定一些二元运算符构造:a x b
其中 a 和 b 是表达式,x 是一些二元运算符,然后首先是 a
和 b
必须进行评估,然后将 x
运算符应用于如此获得的值。除非运营商明确规定了一个命令(例如 ||
和 &&
运营商这样做;他们 promise 短路,即不评估 b
完全没有,如果 a
是这样的 b 不能影响结果) - 那么 C(++) 编译器可以自由地发出代码,以便评估 b
在 a
之前,反之亦然。
C 充满了这样的“应该”和“可能”:C 规范旨在允许 C 代码在各种芯片上编译,并为编译器提供了很大的余地来应用影响深远的优化.到目前为止,简单的原始数据类型具有未指定的位宽。
与几乎所有东西都被锁定的 Java 相比:Java 代码中很少有方面是故意未指定的,并且编译器处于“正常运行”状态,并且在允许发出的字节码方面非常有限(在 java 中,优化留给运行时/热点编译器,而不是 javac
)。
这就是为什么,在 java 中,规范 DOES 明确定义了应该如何解析 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 章)。
关于java - 谁能解释为什么 C 和 Java 的输出不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62836083/