赋值运算符链理解

时间:2018-06-04 03:14:55

标签: java

有人可以解释下面代码的输出

int a=10;
a = a -= a+= a -= a += a;

output : 10 

我无法得到如何给出10?

2 个答案:

答案 0 :(得分:9)

a += a表示a = a + a

同样,a -= a表示a = a - a

我不确定哪种方式适合启动,但如果我使用上面的方法从右侧转换给定代码,

   a += a                     >     a = a + a;
   a -= a += a                >     a = a - (a + a);
   a+= a -= a += a            >     a = a + (a - (a + a ));
   a -= a+= a -= a += a       >     a = a - (a + (a - (a + a)));
   a = a -= a+= a -= a += a   >     a = a - a - a + a + a;

其中-a -a + a + a互相取消,结果为a = a,即10

答案 1 :(得分:1)

这里有多个概念在起作用。

  1. 第一个是Operator Associativity
  2.   

    在编程语言中,运算符的关联性是一个属性,用于确定在没有括号的情况下如何对相同优先级的运算符进行分组。

    Assignment operator is right associative运算符意味着在没有括号的情况下使用多个赋值运算符来计算表达式,我们将从右侧开始进行求值。这决定了优先级。

    从技术上讲,我们讨论的是Addition assignment +=Subtraction assignment -=,它与扩展后的赋值运算符相同。

    a = a -= a+= a -= a += a;
    

    相同
    a = (a -= (a+= (a -= (a += a))));
    

    更改表达式后,很明显答案是10

    1. 第二个是L-Value and R-Value,简单地L-Value是一个表达式,它可以根据编程语言的规则出现在表达式的left hand side of an assignment操作中,类似于R-Value一个表达式,可以出现在right hand side of assignment
    2. 许多流行的编程语言允许表达式a = bR-Value表达式,它返回具有相同类型的L-Value变量的值。

      注意:表达式中的所有运算符都有一个返回值,类型为function

      a = b中,aL-Value,因此返回值和类型为a

      因此a = b = c相当于a = assign(b, c),其中TypeA assign(TypeA a, TypeB b)函数签名在大多数情况下可以表示赋值操作。

      TypeA assign(TypeA a, TypeB b)
      
      1. 评估从左到右开始变量。这意味着在解析期间解析器将开始用从左到右的值替换变量。

        例如,a += (a += a) => a = a + (a = a + a)在编译器开始评估第一个运算符之前将变为a = 10 + (a = 10 + 10)

        第一个被评估的运算符将是最内部括号中具有最高优先级的运算符。

      2. 牢记这些规则我们可以看到下面的评估

        a = a -= a+= a -= a += a;
        //after deciding precedence of operators
        a = (a -= (a+= (a -= (a += a))));
        //after addition assignment expantion
        a = (a = a - (a = a + (a = a - (a = a + a))))
        //First pass of parser
        a = (a = 10 - (a = 10 + (a = 10 - (a = 10 + 10)))) //2nd pass, current a = 10
        a = (a = 10 - (a = 10 + (a = 10 - (20))))          //3rd pass, current a = 20
        a = (a = 10 - (a = 10 + (-10)))                    //4th pass, current a = -10
        a = (a = 10 - (0))                                 //5th pass, current a = 0
        a = 10                                             //6th pass, current a = 10