黑马程序员技术交流社区

标题: 关于运算优先级的疑问,手动和编译器结果不同... [打印本页]

作者: 折纸时代    时间: 2012-11-10 17:33
标题: 关于运算优先级的疑问,手动和编译器结果不同...
本帖最后由 司懿卓 于 2012-11-11 17:31 编辑

public class TheGameTest
{
          public static void main(String[] args)
          {
                        int a = 5; int b = 4;
                       int c = a++ - --b * ++a / b-- >>2 % a--;
                       System.out.println(c);
           }
}

上面是代码部分. 运算符优先级(上面所包含的):
第一个:  ++ --  (自加,自减)
第二个:  * / % ( 乘,除和求余)
第三个:   +  - (加,减)
第四个: >> (右位移)

这是四个运算符的等级,单目最前,位移最后.. 可是,我手动的结果是 int c = 0 ;
但是,用编译器运行的结果是int c =  -1 ;
其中,有个想法是自加或自减  ++a ;a++ ;的运算符为最优先,所以先自身运算(再放入表达式内).
我知道这个想法是错误的,但结果依旧是0.

这个是分解动作:                              
                                                          //因为 a++(a--) 在其表达式内是先加入运算在进行赋值,就是说表达式内a++ =5,其值不变
int c = a++ - --b * ++a / b-- >>2 % a--;
      c = 5++ - --4 *  ++5/4-- >> 2 % 5--
      c = 5 - 3* 6/4 >> 2%5               //单目运算符优先级最高
      c = 5 - 4 >> 2                             // 3*6/4 是int 类型 结果取整 为4 , 2%5=2
      c = 1 >> 2                                  //  减法优先于 位移运算符
      c = 0                                            // 1 右位移2次 结果为0
(表达式最好不要这样写,真的很头晕...)
哪位朋友能帮忙解惑?? 或者指出我计算时的错误..

===================  下面是问题解决  ============================

表达式   int c = a++ - --b * ++a / b-- >>2 % a--;
a 在表达式内 先a++, 再++a ,然后a-- .
其实,a的值有变3次,
第一个a++,没有为表达式提供改变 ,但是,为后面的++a赋了一次值.
第二个++a,开始自加然后(因为前面的a++的赋值) ++a=7,后面a--的值因为前面有变动所以a--的值为7,
但是因为要参与2%a--的运算,所以无意义,2%7的值 为 2..

b在表达式内出现了2次,它的值也变动了
--b 先自减然后赋给自身 --b=3 ,然后是b--,因为前面已经赋给自身,所以b--也继承了前面的值 现在 b--=3
因为,b--是先运算后自减,所以b--的值 依旧是3 不变!
因此上面的式子应该这样运算:
int a = 5; int b = 4
int c = a++ - --b * ++a / b-- >>2 % a--;
c = 5 - 3*7/3 >>2 % 6   
c = 5 - 7 >> 2
c = -2 >> 2
c = -1     //-2右移两次结果是 -1 ..  


==================  问题的根源所在  ====================
因为 ++a 和 a++ 是两种自加方法,有所不同..
++a 是先自加再参与运算 ;
a++ 是先参与运算在自加;
下面来解析下不同:

(1)  int a = 0 ;                                                                                       |     (2) int c = 0;
      int b = ++a + ++a ;                                                                       |           int d = c++ + ++c ;
      int b = (0+1) + (1+1) ;                                                                   |          int d = (0) + (1+1);
       int b = 3 ;                                                                                      |           int d = 2;
第一个a++ 先自加 值为:1 第二个 a自加之前值已经为1 , 再自加为2     |       第一个c++是先运算再自加,值为0. 第二个++c
                                                                                                                     因为之前的c++,所以运算后赋值自身,所以++c值为2;
上面的两个表达式也算是找出了最上面问题的所在了...

希望斑竹给个分分吧...

作者: 黑马十八期0513    时间: 2012-11-10 18:33
int c =a++ - --b * ++a / b-- >> 2 % a--
    c =5 - 3*7/2 >>2%6
    c =5 -10>>2%6
    c =5 -5%6
    c =5 -6
    c =-1
作者: 黑马十八期0513    时间: 2012-11-10 18:39
不对,算错了。应该是
c = 5 - 3 * 7 / 2  >> 2  %  6
  = 5 - 10>>2 % 6
  = 5 - 2 % 6
= 5 - 6
=-1
作者: 折纸时代    时间: 2012-11-10 20:34
姜伟 发表于 2012-11-10 18:39
不对,算错了。应该是
c = 5 - 3 * 7 / 2  >> 2  %  6
  = 5 - 10>>2 % 6

2%6 的值好像是2吧...

++a 的值为什么是7??
可以说它是最先计算的,先自加然后赋给自身 应该是6啊

而且你的式子中 位移符是在 双目符前面计算的... 这优先级貌似有点乱了..
作者: 折纸时代    时间: 2012-11-10 20:59
姜伟 发表于 2012-11-10 18:39
不对,算错了。应该是
c = 5 - 3 * 7 / 2  >> 2  %  6
  = 5 - 10>>2 % 6

nt a = 5; int b = 4
int c = a++ - --b * ++a / b-- >>2 % a--;
c = 5 - 3*6/3 >>2 % 6   
c = 5 - 6 >> 2
c = -1 >> 2
c = -1     //-1右移两次结果还是 -1 ..  

已经找到问题了..  不过还是谢谢了.
作者: 黑马十八期0513    时间: 2012-11-10 22:36
司懿卓 发表于 2012-11-10 20:59
nt a = 5; int b = 4
int c = a++ - --b * ++a / b-- >>2 % a--;
c = 5 - 3*6/3 >>2 % 6   

我是新手,有些东西我也不太清楚,现在也还在学。不过-1>>2后的结果不会是-1,右移后最高位用1补齐的。
int a=5, a++是对a进行自加运算,此时a的值已经是6了,  ++a又对a进行自加运算,a的值此时为7。
不管加号是在a前面还是后面,a的值都会增加。
作者: 折纸时代    时间: 2012-11-11 08:52
本帖最后由 司懿卓 于 2012-11-11 16:28 编辑
姜伟 发表于 2012-11-10 22:36
我是新手,有些东西我也不太清楚,现在也还在学。不过-1>>2后的结果不会是-1,右移后最高位用1补齐的。
i ...

a++是先参与运算再自加,所以在这个表达式内a++的值,不变还是5..
-1>>2 的值,你可用编译器验证下..

-1的补码 全是1 ,不管右移几位(long不超过63),只要是带符号右移,结果都是-1..

-1的原码是 32个1取反,结果是31个0 .然后加1 .. 值是1,但是前面有一个符号位..  所以值是-1 .
作者: 黑马十八期0513    时间: 2012-11-11 10:06
a++是先运算再自加,a++是5,但是此时a进行过自加运算,所以a的值变成了6.  后面++a是先自加再运算,所以a的值就为7。
int a =0;      
int b=a++ + ++a  = 0 + 2 =2
我说了好几个都不准确,但是这个是对的。  a++的值是5,++a的值是7,而不是6
作者: 折纸时代    时间: 2012-11-11 17:15
姜伟 发表于 2012-11-11 10:06
a++是先运算再自加,a++是5,但是此时a进行过自加运算,所以a的值变成了6.  后面++a是先自加再运算,所以a ...

之前一直纠结,现在 通过你给的
int a = 0 ,
int b = a++ + ++a =2 找到的根源


===================  下面是问题解决  ============================

表达式   int c = a++ - --b * ++a / b-- >>2 % a--;
a 在表达式内 先a++, 再++a ,然后a-- .
其实,a的值有变3次,
第一个a++,没有为表达式提供改变 ,但是,为后面的++a赋了一次值.
第二个++a,开始自加然后(因为前面的a++的赋值) ++a=7,后面a--的值因为前面有变动所以a--的值为7,
但是因为要参与2%a--的运算,所以无意义,2%7的值 为 2..

b在表达式内出现了2次,它的值也变动了
--b 先自减然后赋给自身 --b=3 ,然后是b--,因为前面已经赋给自身,所以b--也继承了前面的值 现在 b--=3
因为,b--是先运算后自减,所以b--的值 依旧是3 不变!
因此上面的式子应该这样运算:
int a = 5; int b = 4
int c = a++ - --b * ++a / b-- >>2 % a--;
c = 5 - 3*7/3 >>2 % 6   
c = 5 - 7 >> 2
c = -2 >> 2
c = -1     //-2右移两次结果是 -1 ..  




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2