在Java中,先执行哪个命令+&引用;或++&引用;?

在Java中,先执行哪个命令+&引用;或++&引用;?,java,operator-precedence,Java,Operator Precedence,我在Java中尝试了以下代码 t1 = 5; t2 = t1 + (++t1); System.out.println (t2); 我的观点是,由于++的优先级高于+,因此上面的内容变得 t2 = t1 + (++t1); t2 = t1 + 6; // t1 becomes 6 here t2 = 6 + 6; t2 = 12; 然而,我得到了t2的答案11。有人能解释一下吗?你的逻辑很接近,但不完全正确。+运算符的求值顺序为从左到右。t1在二进制op,LHS之前,然后增量在该二

我在Java中尝试了以下代码

t1 = 5;
t2 = t1 + (++t1);
System.out.println (t2);
我的观点是,由于++的优先级高于+,因此上面的内容变得

t2 = t1 + (++t1);
t2 = t1 + 6;      // t1 becomes 6 here
t2 = 6 + 6;
t2 = 12;

然而,我得到了t2的答案11。有人能解释一下吗?

你的逻辑很接近,但不完全正确。+运算符的求值顺序为从左到右。t1在二进制op,LHS之前,然后增量在该二进制op的RHS上。首先执行LHS

t2 = t1 + (++t1);
t2 = 5 + 6;      // t1 becomes 6 here as a side effect before being read on the RHS
t2 = 11;
想象成你拥有的一棵树

    +
  /   \
 t1   ++t1
优先顺序

当两个运算符共享一个操作数时,优先级较高的运算符优先。例如,1+2*3被视为1+(2*3),而1*2+3被视为(1*2)+3,因为乘法的优先级高于加法

结合性


当两个具有相同优先级的运算符时,将根据其关联性对表达式求值。例如,x=y=z=17被视为x=(y=(z=17)),将所有三个变量的值保留为17,因为=运算符具有从右到左的关联性(赋值语句的计算结果为右侧的值)。另一方面,72/2/3被视为(72/2)/3,因为/运算符具有从左到右的关联性

第二行中t1的值为5

t2 = t1 + (++t1)
t2 = 5 + 6;      // t1 becomes 6 here


因此,首先将t1求值为
5
,然后将
++t1
求值为
6
,因此从左到右求值结果为
11

t1 + (++t1)     // Left side is evaluated to 5, right side evaluated to 6...
5  + (6)        // ...and as a side effect t1 becomes 6

11

评估结果从左到右。所以实际上接下来会发生什么

t2 = t1 + (++t1);
t2 = 5 + 6;      
t2 = 11;
1) t1 = 5;
2) t2 = t1 + (++t1); 
3) t2 = t1 + (t1 = t1 + 1), 
4) t2 = 5 + (t1 = t1 + 1)
5) t2 = 5 + (t1 = 6)
6) t2 = 5 + 6 = 11

++x在使用变量x之前执行,x++在使用变量x之后增加x:

x=5;
y=x++;
y is 5;
and x is 6

x=5;
y=++x;
y is 6;
and x is 6

为了给Chris K增加一点

关联性是从左到右的

所以

这相当于

temp = t1 + 1
t2 =  t1 + temp;
t1= temp;

你几乎是正确的,但你微妙地误解了优先规则的工作原理

比较这两种情况:

int t1 = 5;
int t2 = t1 + (++t1);
System.out.println (t2);

t1 = 5;
t2 = (++t1) + t1;
System.out.println (t2);
结果是:

11
12
优先级确实表示在
+
之前计算
+
,但直到它到达表达式的该部分时才适用

您的表达式的形式为
X+Y
其中
X
t1
Y
(++t1)

首先计算左分支,即
X
。 然后对右分支,即
Y
,进行评估。 只有在计算
Y
时,才会执行
++
操作


优先规则只说明
++
Y
表达式的“内部”,它们没有说明任何操作顺序。

另一种思考方式是扩展++表达式:

++t1
与放置
t1=t1+1
相同

1) t1 = 5;
2) t2 = t1 + (++t1); 
3) t2 = t1 + (t1 = t1 + 1), 
4) t2 = 5 + (t1 = t1 + 1)
5) t2 = 5 + (t1 = 6)
6) t2 = 5 + 6 = 11
如果将顺序颠倒为
t2=(++t1)+t1
然后表达式将扩展为:

1) t2 = (t1 = t1 + 1) + t1     
2) t2 = (t1 = 5 + 1) + t1
3) t2 = (t1 = 6) + t1
4) t2 = 6 + 6 = 12

在复合表达式中尽量避免使用
++/--
。虽然这种行为在Java中定义良好,但在perl中会产生不同的结果(如12),在C/C++中会产生未定义的行为。此外,它通常使表达式更难快速分析。。(举例来说,也许)在C语言中这被认为是“未定义的行为”,这一事实应该让你明白,在任何语言中使用这种结构可能都不是一个好主意。在我看来,有太多的机会得不到你所期望的答案。帮大家一个忙,使用两行代码——你未来的自己会感谢你的……我认为这是一个很好的问题,但有趣而不是有用的:你应该避免在复合表达式中使用递增/递减运算符(见上面的注释),省得你自己头疼。另请参见:IMO“[逻辑]不太接近”。维韦克在他的问题中混淆了评估顺序和优先级。需要指出的是,它们完全不同。++x和x++可以同时执行,但它们返回另一个值++x返回新值,x++返回旧值。我喜欢/讨厌当你看到这两个语句时,你似乎把
a=b+c
变成
a=c+b
,但它们产生了两个不同的结果。实际上,这更像
temp=t1;t1++;t2=temp+t1
你能加几行解释为什么你认为你的答案最适合回答原来的问题吗?谢谢
1) t2 = (t1 = t1 + 1) + t1     
2) t2 = (t1 = 5 + 1) + t1
3) t2 = (t1 = 6) + t1
4) t2 = 6 + 6 = 12
enter code here
t1 = 5;
t2 = t1 + (++t1);
// it takes 5 for t1 and as it moves further to (++t1), it increments t1 to 6, so it takes 6 for  (++t1)
t2 = 5 + 6;
// (++t1) this increments t1 by 1 then return new value. So (++t1)=6
// (t1++) this returns old value n then increments t1 by 1. So (t1++)=5