关于b=++b和b = b += 1的问题探讨

来源:互联网 发布:淘宝优惠券怎么发放 编辑:程序博客网 时间:2024/05/29 03:59
问题一: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,所以就出现了这样的结果了