【问题标题】:Its correct answer is 22. But I am getting 24. Where am I wrong? I evaluate the assignment operator += in last as it has the lowest precedence它的正确答案是 22。但我得到 24。我错在哪里?我最后评估赋值运算符 += 因为它的优先级最低
【发布时间】:2021-10-21 12:53:07
【问题描述】:
class Output
{    
    public static void main (String[] args)   
    {
        int a = 5;
    
        a += 5+ (++a) + (a++);
        System.out.print(a);
    }
}

评价:

a += 5 + (++a) + (a++)

=> a+= 5 + 6 + (a++) [++a :increment value of a and then use it. So:increment a = 6, then use a=6]

=> a+= 5 + 6 + 6 [a++ :use and then increment value of a. So: use a=6, then increment a=7]
    
=> a+= 11 + 6
    
=> a+= 17
    
=> a = a+17
    
=> a = 7 + 17
    
=> a = 24

【问题讨论】:

  • edit发帖并正确格式化代码。
  • a = 5 + 5 + 6 + 6; 我们从a +=a = 5 开始。所以a = 5 + 5。一旦运行时达到++a,它就会变成6。所以a = 5 + 5 + 6 + 6a++直到下一行才生效)。
  • 但是我们应该最后评估 += 运算符,因为它的优先级最低。最后在评估所有其他运算符之后,a 变为 7。所以 7 不应该是 a = 7 + 5 + (6) + (6) 而不是 a = 5 + 5 + (6) + (6)?

标签: java operators


【解决方案1】:

+= 运算符与所有复合运算符一样,首先在计算所有其他操作数之前以及实际执行任何操作之前计算左侧的变量。这是由JLS, Section 15.26.2 指定的:

如果左侧操作数表达式不是数组访问表达式,则:

  • 首先,计算左侧操作数以生成变量。如果这个求值突然完成,那么赋值表达式出于同样的原因突然完成;不计算右侧操作数,也不发生赋值。
  • 否则,保存左侧操作数的值,然后计算右侧操作数。如果这个求值突然完成,那么赋值表达式也会因为同样的原因而突然完成并且不会发生赋值。
  • 否则,左侧变量的保存值和右侧操作数的值将用于执行复合赋值运算符指示的二元运算。如果此操作突然完成,则赋值表达式会出于同样的原因而突然完成并且不会发生赋值。
  • 否则,二进制运算的结果将转换为左侧变量的类型,经过值集转换(第 5.1.13 节)到适当的标准值集(不是扩展指数值集),并将转换结果存储到变量中。

(我的粗体强调)

这意味着a 被评估(并保存)到左侧的5之前a++++a 在右侧被评估。右侧确实计算为17,但因为左侧仍然是5,所以总和是22,而不是24

【讨论】:

  • 很好的解释。感谢您消除我的疑问。
【解决方案2】:

表达式

a += 5 + (++a) + (a++);

等价于

a = a + 5 + (++a) + (a++);

意思是a的新赋值是操作数从右到左的总和(因为从左到右的关联性),计算方式如下:

  • 取变量a:计算为5
  • 添加常量5
  • 增加变量a然后评估结果:6
  • 评估变量a然后递增它。 总和中使用的值将是评估值:6

总和是22

【讨论】:

    猜你喜欢
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    相关资源
    最近更新 更多