C和JAVA中增量-减量运算符的差异[重复]
Posted
技术标签:
【中文标题】C和JAVA中增量-减量运算符的差异[重复]【英文标题】:Difference in Increment-decrement operator in C and JAVA [duplicate] 【发布时间】:2013-07-15 03:11:02 【问题描述】:请考虑以下陈述:
int a[]=1,2,3,4,5,6,7,8;
int i=0,n;
n=a[++i] + i++ + a[i++] + a[i] ;
根据我的逻辑,n 应该是 10。但是我在 c 中得到不同的输出(输出为 7) 但是在 java 中,我得到的预期结果是 10。增量和减量运算符在 c 和 java 中的工作方式有什么不同。
这是我的确切 c 和 java 代码:
#include <stdio.h>
int main()
int a[]=1,2,3,4,5,6,7,8;
int i=0,n;
n=a[++i] + i++ + a[i++] + a[i] ;
printf("%d",n);
getch();
return 0;
带有输出的Java代码:10
public class HelloWorld
public static void main(String []args)
int a[]=1,2,3,4,5,6,7,8;
int i=0,n;
i=0;
n=a[++i] + i++ + a[i++] + a[i] ;
System.out.println(n);
【问题讨论】:
Java 设计者选择精确定义所有增量等情况的结果,尽管 JLS 建议在一个语句中避免多重副作用。 C++ 标准未定义某些情况。 您的意思是结果是 7 而不是 10 的原因是所谓的“c 的未定义行为”实际上如果您从右到左而不是从左到右评估表达式,则答案可以是 7。您确定它与运算符关联性无关吗? 有趣的是,每个人都提出了同样的问题。更何况他们都遇到了未定义的行为。也许C应该被称为未定义的语言。 有谁会写出这样的代码? 比@duffymo 直率一点——不要这样写代码。我当然希望这个问题只是出于好奇,而不是你在实践中实际做的事情。 【参考方案1】:在C
中,这是一种未定义的行为。由于C
不保证表达式中单个操作的求值顺序。
【讨论】:
如果您从右到左而不是从左到右评估表达式,实际上答案可能是 7。您确定它与运算符关联性无关吗? 有什么我需要特别记住的关于 c 中表达式的求值顺序(如果有的话,我在哪里可以找到一些定义明确的规则?) @AbhasTandon。你不能。这就是为什么它被称为未定义的行为。一般来说,您应该避免在同一个表达式中多次修改同一个变量。 undefined behavior 似乎是新的 Hello World。【参考方案2】:关于来自c99
draft standard6.5.2
的C:
在上一个和下一个序列点之间,一个对象应该有它的存储值 通过表达式的评估最多修改一次。此外,先验值 应为只读以确定要存储的值。
它引用了以下未定义的代码示例:
i = ++i + 1;
a[i++] = i;
draft 2011 standard 中的部分也相同,但读起来有点尴尬。这是sequence point 的一个很好的参考。
15.7
部分是JLS
中的相关部分:
Java 编程语言保证运算符的操作数看起来是按照特定的计算顺序计算的,即从左到右。
建议代码不要过度依赖本规范。当每个表达式最多包含一个副作用时,代码通常会更清晰
【讨论】:
【参考方案3】:为了补充 Rohit 的答案,如果您分别执行每个步骤,则会给出答案 10。这只是强调了i++
和++i
的执行可能不会按照将参数添加到值n
的顺序发生。
#include <stdio.h>
int main()
int a[]=1,2,3,4,5,6,7,8;
int i=0,n;
n=a[++i] + i++ + a[i++] + a[i] ;
printf("%d\n",n);
i=0;
n=0;
n=a[++i];
printf("%d\n",n);
n+=i++;
printf("%d\n",n);
n+=a[i++];
printf("%d\n",n);
n+=a[i];
printf("%d\n",n);
return 0;
【讨论】:
以上是关于C和JAVA中增量-减量运算符的差异[重复]的主要内容,如果未能解决你的问题,请参考以下文章