为什么这个表达式i + = i ++与Java和C不同? [英] Why does this expression i+=i++ differs from Java and C?

查看:122
本文介绍了为什么这个表达式i + = i ++与Java和C不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know about the prefix and posfix operation... the difference between ++i and i++ and so.

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

But I think I'm missing something here. Below you can find the code:

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中尝试了相同的代码:

I tried the same code in 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中的相同代码会增加值?

Why i+=i++ doesn't increment i while the same code in C it increments the values?

推荐答案

Java

在Java中,表达式具有明确定义的含义。 复合赋值运算符的规范说:

In Java, the expression has a well-defined meaning. The specification for the compound assignment operators says:


E1 op = E2 形式的复合赋值表达式相当于 E1 =(T)((E1)op(E2)),其中 T E1 的类型,但 E1 除外>仅评估一次。

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:


  • 首先,左侧操作数是评估以产生变量。如果此评估突然完成,则赋值表达式
    突然完成,原因相同;右边的操作数不是
    评估的,也不会发生任何分配。

  • 否则,保存左边操作数的值,然后评估右边的操作数。如果此评估突然完成
    ,那么分配表达式突然完成
    同样的原因并且不会发生任何分配。

  • 否则,保存的左手值变量和右侧操作数的值用于执行复合赋值运算符指示的二元运算
    。如果此操作
    突然完成,则赋值表达式突然完成
    ,原因相同且没有赋值。

  • 否则,二进制操作的结果将被转换到左侧变量的类型,受到值集转换
    (§5.1.13)到相应的标准值集(不是
    扩展指数值集),以及结果转换是
    存储到变量中。

  • 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 ++ 被后续作业覆盖。

Because the value of the left-hand side is saved at the start, and then added to the value of right hand side, and because expression evaluation in Java is left-to-right, the modification of i caused by i++ is overwritten by the subsequent assignment.

所有这些意味着

i += i++;

相当于

i += i;

C

在C中表达式

i += i++;

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

has undefined behavior. And so anything might happen when you execute this code. Which means that you cannot predict what value i will have after the statement completes.

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

And so it is entirely to be expected that the output from your C program differs from the output from your Java program.

这篇关于为什么这个表达式i + = i ++与Java和C不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆