C与Java的逻辑差异

C与Java的逻辑差异,java,c++,c,operators,Java,C++,C,Operators,用C语言编译并运行这段代码 #include <stdio.h> int main() { int a[] = {10, 20, 30, 40, 50}; int index = 2; int i; a[index++] = index = index + 2; for(i = 0; i <= 4; i++) printf("%d\n", a[i]); } 输出:102054050 为什么两种语言的输出有差异,Java的输出是可以理解的,但我不

用C语言编译并运行这段代码

#include <stdio.h>

int main()
{
  int a[] = {10, 20, 30, 40, 50};
  int index = 2;
  int i;

  a[index++] = index = index + 2;
  for(i = 0; i <= 4; i++)
    printf("%d\n", a[i]);
}
输出:
102054050

为什么两种语言的输出有差异,Java的输出是可以理解的,但我不能理解C的输出


还有一件事,如果我们应用前缀
++
操作符,我们在两种语言中得到相同的结果,为什么?

这是因为
a[index++]=index=index+2调用C中未定义的行为。
看看

从链接:

…第二句话说:如果在一个完整表达式中写入一个对象,那么在同一个表达式中对该对象的任何和所有访问都必须直接参与要写入的值的计算。该规则有效地将合法表达式限制为访问明显先于修改的表达式。例如,旧的备用i=i+1是允许的,因为i的访问用于确定i的最终值。榜样

 a[i] = i++
是不允许的,因为i的一个访问(a[i])与最终存储在i中的值无关(发生在i++),因此,无论是为了我们的理解还是为了编译器的理解,都没有很好的方法来定义访问应该在存储递增值之前还是之后进行。由于没有好的方法来定义它,标准声明它是未定义的,并且可移植程序不能使用这样的结构。 类似于
a[i++]=i
(调用UB),您的表达式也调用UB

您的表达式也有类似的行为


但是,
Java

中对行为进行了很好的定义,
a[index++]=index+2
(大部分结果相同)是未定义的。老实说,我得查一下标准才能确定。@Michiel:是的,那也是UB,同样的原因。+1-回答得很好。您可以添加一个关于Java中定义的代码片段吗?出于好奇:-)
a[index++]=index+2
也是未定义的行为。可以这样想:标准说增量发生在语句结束之前的某个时间,并且没有指定除此之外的任何顺序。因此,无法知道增量是发生在加法之前还是之后。(这与
++索引
相同-虽然下标值是原始
索引+1
,但该值实际存储到
索引
中的时间尚未定义)委员会选择将其称为未定义,而不是在标准中未指定,这意味着任何行为都是合法的。@Topher:C和Java在这里有非常不同的目标。C语言的设计目的是让编译器有很大的自由来提高性能,这与系统实现语言相适应。Java被设计来确定所有可能的行为,使程序员更容易操作。C和Java都非常成功。但是谁会(在真实的应用程序中)编写这样的代码呢?@CarlosHeuberger我知道你不习惯
C++
tag@RyanHaining我不明白,但这条评论是从2010年1月8日开始的,当时这个问题没有标注
c++
。我仍然认为,<代码> [index ++] = index = index + 2 < /Code >在C++、C++和java(python)中都不好——通过评论投票,我相信我不是单独的,或者<代码> C++ +/Code >标签意味着代码是不可读的(比如代码高尔夫球?),并且看到唯一的答案,而且C对此有点困惑…@CarlosHeuberger这是个笑话。至少有一半的
[c++]
关于该语言的问题可以用“你为什么要写这个?”来回答,顺便说一句,这不是合法的python。
 a[i] = i++