现在的位置: 首页 > 综合 > 正文

黑马程序员-关于b=++b和b = b += 1的问题探讨

2013年10月08日 ⁄ 综合 ⁄ 共 2349字 ⁄ 字号 评论关闭
问题一:byte b = 1; b = b += 1;   
问题二:byte b = 1; b = ++b;  

问题一和问题2中的结果在编译时是没有问题的,哪位朋友可以帮我解释一下为什么吗?
byte b=1,这个我知道肯定是没问题了,int类型的1自动转化为了byte类型并赋值给了b,但是b + b+=1这个有点不太理解了,
b += 1是不是相当于b = b+1,如果是这样的话,编译应该有问题才对,b+1运算后的结果是int类型,需要强转才能赋值给byte类型的。

第二个问题,b = ++b,先运算++再赋值,感觉也相当于b = b+1,为什么这个编译也不报错呢

经过仔仔细细又看了两遍老毕的“15-Java语言基础(算术运算符_2&赋值运算符).avi”,已经有了答案了,如答案有不足之处,希望大家指出来:
一:byte b = 1; b = b += 1;   
二:byte b = 1; b = ++b;  
问题一:
    对于第一个运算,首先,byte b = 1;实际上这个值是编译器先进行了一次检查,范围在byte范围内,则编译通过,
    同时将1这个int类型的值在底层转化为了byte类型赋给了b;
    再说说b = b += 1;这个运算是将b += 1的计算结果赋给了b,所以我们只说b += 1的运算过程就行了,
    b += 1,其实等价于 b = (byte)(b+1);底层会对这个结果进行强转的,所以它编译的时候没事,如果b是127,
    那么加1后变成128了,成了int类型了,超过了byte类型的最大范围了,怎么办?这时候底层会强转,把int类型的
    前面三个高位丢弃,丢弃后,如果剩下的一位中,最高位为1,则取反加一,就成了负数了,如果最高位为0,直接把
    值赋给b
                        
问题二、
    b = ++b,这个运算的过程是,先进行++b的运算,再把运算后的结果赋给b,++b计算后是一个int类型的,
    不管结果等于多少,底层会进行一个强转,也就是说++b就相当于 b = (byte)(b+1),所以这个编译也没有问题,但是如果你
    搞个byte b = 127; b = ++b;结果也会跟问题一一样,大家可以测试一下

另外还有几个类似的问题在此一起说明:

1.
    int count = 0;
    count = count + count++;
    System.out.println(count);
    2.
    int count = 0;
    count = count++ + count;
    System.out.println(count);
    3.
    int count = 0;
    for (int i = 0; i < 100; i++) {
    count = count + count++;
    }
    System.out.println(count);
    4.
    int count = 1;
    for (int i = 0; i < 100; i++) {
    count = count + count++;
    }
    System.out.println(count);

复制代码

    第一个问题: 要明白count = count + count++的结果,首先要知道两个问题:
    第一个是这个运算的运算顺序,第二个是count++操作做了什么事,对于运算顺序,肯定是先运算等式右边的
    再赋值给左边的变量,右边的运算是从左到右算的,明白了这两个问题再来看题就不复杂了. count = count +
    count++;先运算右边,右边从左到右算, 我们要是知道count++的结果就知道了右边的结果了,
    count在跟左边的count运算之前,会先进行一个复制,将原来的值复制一份,然后它本身的原值会自增,
    需要注意的是原值的自增跟复制后的数据是没有关系的,自增后,原值变成1了, 这时候进行count +
    count++进行运算,但是count++参与运算的是复制出来的那份值而不是自增后的结果,
    由于等式右边的左边的count是在count++运算前就有值的,所以它是0,而count++的结果是0,所以 就是 0 + 0,
    然后将结果赋给了等式左边的count,结果打印就是0

    第二个问题: 原理其实跟第一个问题差不多,但结果肯定是不一样的,因为等式右边的运算是要从左到右的,count++ + count,
    count先复制一份数据也就是0出来,然后进行自增这时候原值变为1了,而count++参与运算用的是复制出来的0参与
    运算的,所以count++ + count实际上就是 0 + 1,为什么这里是0+1而不是0+0呢,因为count++运算虽然用的是复制出来
    的那份数据,但是它本身的值已经自增到了1,而count++右边的那个count拿的是自增后的原值也就是1, 所以这个打印结果是1

    第三个问题: 如果你第一第二个问题已经看懂了,我相信第三个问题已经不言自明了,count = count + count++;打印的结果
    其实就相当于count = count + count;虽然两者底层运算有点差异,但结果是一样的, 所以这个for循环不管有多少次
    结果都是0 = 0 + 0,结果都打印为0

    第四个问题: 原理也是一样的因为count = count + count++的结果就相当于count = count + count;
    所以再来看第四个问题的结果就不为怪了,但是第四个问题有些人可能会感到奇怪,因为结果是0,如果我们自己算也会感到奇怪,
    count首先等于1,for循环第一次1 = 1 + 1++结果为2(不解释了吧),再运算的数据会越来越大为什么会为0呢?
    我也感到纳闷,但我知道一旦这个count有一次结构为0,后面的所有for循环计算出的结果都为0了,
    所以我们找到为0的时候for循环中的i等于多少,
    经测算i为31的时候,结果为0,而i为30的时候count等于-2147483648,二进制为
    10000000000000000000000000000000,这时候count + count++, 就相当于count *2
    了(两个相同的数据相加相当于乘以2, 这个不用解释吧),乘以2就相当于左移1位,结果为0,所以就出现了这样的结果了

抱歉!评论已关闭.