C 和 Java 中的逻辑差异

2022-09-01 06:40:42

在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]);
}

输出:10 20 4 40 50

现在在Java中使用相同的逻辑

class Check
{

  public static void main(String[] ar)
  {
    int a[] = {10, 20, 30, 40, 50};
    int index = 2;

    a[index++] = index = index + 2;
    for(int i = 0; i <= 4; i++)
      System.out.println(a[i]);
  }
}

输出:10 20 5 40 50

为什么两种语言的输出有差异,输出是可以理解的,但我无法理解输出JavaC

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


答案 1

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

从链接:

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

 a[i] = i++

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

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

该行为在 中得到了很好的定义。Java


答案 2