java - 为什么 C 和 Java 对以下循环的处理方式不同

标签 java c

用 C 语言

#include <stdio.h>  
int main(){  
  int x=100;  
  x=x++ + x++;  
  printf("x :  %d\n",x); // prints 202  
  return 0;
}

在Java中

class Demo{ 
  public static void main(String args[]){  
    int x=100; 
    x=x++ +  x++;  
    System.out.printf("x : %d",x); // prints 201  
  }
}

为什么这两种语言打印不同的值?会发生什么“x=x++ + x++;”线?

最佳答案

Java 和 C 是不同的语言,因此并非所有在语法上都有效的构造(有很多,因为 Java 的语法建立在 C 的语法之上)在两者中都必须具有相同的含义。

结构

int x=100; 
x=x++ +  x++;

就是一个例子。在Java中,表达式的计算顺序被指定为从左到右,并且x++中递增x的副作用必须在下一部分之前发生计算表达式的值。因此,上面的代码 - 除了临时变量 - 相当于

int x = 100;
int left = x++;   // sets left to x's value (100) and increments x, so x is now 101
int right = x++;  // sets right to x's current value (101) and increments x, so x is now 102
x = left + right; // 100 + 101 = 201

在 Java 中。

在 C 中,未指定组成表达式的子表达式的计算顺序,此外,在 x++ 中递增 x 的副作用可能发生在上一个序列点和下一个序列点之后的任何时间。

因此,在 C 语言中多次修改同一对象而不插入序列点(旧说法)是未定义的行为,在 1999 版 C 语言标准中,表示为(在第 6.5 节第 2 段中)

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.70)

70) This paragraph renders undefined statement expressions such as

   i = ++i + 1;
    a[i++] = i;
while allowing
    i = i + 1;
    a[i] = i;

当前(2011)版本的标准将“序列点”术语替换为“前后排序”和“未排序”,第 6.5 节第 2 段现为

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)

(脚注 84 是前一个脚注 70)。

x = x++ + x++ 中递增标量对象 x 的两个副作用,以及将右侧的计算值存储在标量对象 x 未排序,因此行为未定义。

编译器可能会拒绝编译包含表达式x++ + x++的程序,或者完全忽略未定义的行为(或介于两者之间的任何行为)。如果程序编译成功,该行的每个运行时行为

x = x++ + x++;

同样有效。该标准对行为没有施加任何限制。

关于java - 为什么 C 和 Java 对以下循环的处理方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16638647/

相关文章:

java - Maven 返回编译失败 : package com. mashape.unirest.http 不存在

java - MAVEN SUREFIRE 插件错误

c - 为什么您认为该代码会出现段错误?

c - 将指向 const 类型的指针初始化为非常量类型

c - 使用execvp后如何释放malloc创建的内存?

java - 读取 XML 与读取 CSV 文件 java

java - Java中的二进制搜索代码无法运行

java - 递归划分正方形区域

c# - 有可能制作一个可以在多种语言中使用的库吗?

scanf 函数后无法继续