java - 为什么这个表达式 i+=i++ 不同于 Java 和 C?

标签 java c

我知道前缀和后缀运算...++i 和 i++ 之间的区别等等。

但我想我在这里遗漏了一些东西。您可以在下面找到代码:

package test;

public class Test
{
    public static void main (String[] args)
    {
        int i=0;

        i+=i++;
        System.out.println(i); // Prints 0

        i = i + (i++);
        System.out.println(i); // Prints 0

        i = i + (i+1);
        System.out.println(i); // Prints 1

    }
}

所以输出是:

0
0
1

我在 C 中尝试了相同的代码:

#include <stdio.h>
#include <string.h>

main()
{
    int i=0;

    i+=i++;

    printf("%d", i);   // prints 1

    i = i + (i++);
    printf("%d", i);   // prints 3

    i = i + (i+1);
    printf("%d", i);   // prints 7
}

输出是:

1
3
7

为什么 i+=i++ 不递增 i 而 C 中的相同代码却递增值?

最佳答案

Java

在 Java 中,表达式具有明确定义的含义。 specification for the compound assignment operators说:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

...

At run time, the expression is evaluated in one of two ways. If the left-hand operand expression is not an array access expression, then four steps are required:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

所以

i += i++;

相当于

i = i + i++;

因为左边的值在开始时被保存,然后添加到右边的值,并且因为Java中的表达式评估是从左到右的,所以 i <的修改i++ 引起,被后续赋值覆盖。

这一切意味着

i += i++;

相当于

i += i;

C

C语言中的表达式

i += i++;

有未定义的行为。因此,当您执行此代码时,任何事情都可能发生。这意味着您无法预测语句完成后 i 的值。

因此,C 程序的输出与 Java 程序的输出完全不同是完全可以预料的。

关于java - 为什么这个表达式 i+=i++ 不同于 Java 和 C?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23553358/

相关文章:

c - 当 sig 0 发送到 TARGET REAL UID == CURRENT EFFECTIVE UID 的进程时,kill 的返回值是多少?

c - 使错误别名为 undefined symbol devone_init

c - 从结构中获取信息并在另一个函数中使用

java - 在 Java 中使用数组的更好的最小值和最大值算法

java - JPA 2.1 hibernate 一对多约束违反重复条目

java - 如何仅从数组列表中计算平均值“计算正数而忽略负数)?

c++ - 使用 MSVC++ 9 进行 C 编程的建议

java - 针对大型数据集存储和匹配名称的有效方法

java - 访问其他包中的 protected 方法?

C 加上 int 和 float,类型变了