在讲类型转换之前,我们先说一下数字是怎么在计算机中存储的。其实数字在计算机中都是用二进制0,1表示的,比如说int a = 3,那么它在计算机中的存储格式为00000000000000000000000000000011。负数是以补码的形式存储的,关于补码可以自己去了解下,这涉及到源码反码的概念。
1.比int小的首先转换成int,unsigned int,long,unsigned long,long long,unsigned long long中最小的一种类型,前提是这种类型能容纳所有原先类型的值。比如说计算b + c时如果b和c都是char类型的话,那么首先把它们转换成int型再做加法。
2.看一下一个比较小的类型转换成比它大的类型会发生什么(如char 转换成int),这里又存在几种情况(如unsigned char 转int,char转int,unsigned char 转unsigned int,char转unsigned int)
(1)unsigned char转int(先把unsigned char提升,提升过程中高位全补0。如a为10,二进制表示就为00001010,先提升到32位为00000000000000000000000000001010,然后再转换成int,见下图)
(2)signed char 转换成int又会发生什么呢,当signed char 为负数时提升到32位时把填充位全填1,当signed char为正数时高位全补0。如下图,当signed char为-128时二进制表示为10000000,首先提升为11111111111111111111111110000000,然后再转换成int,即int 的二进制表示也是11111111111111111111111110000000。a为10时二进制表示就为00001010,先提升到32位为00000000000000000000000000001010,然后再转换成int。
(3)char转换成unsigned int会怎么变化呢。当char为正数时,char先提升到32位,高位补0,然后再转换为unsigned int(就是把提升后的32为二进制给unsigned int)。当char为负数时,先提升到32位,高位补1,然后再把提升后的32位二进制给unsigned int。如下图,当char为10时,二进制表示为00001010,先提升为00000000000000000000000000001010,然后再转换成unsigned int,我们知道二进制为00000000000000000000000000001010的unsigned int还是10。当char为负数时,令char等于-128,先提升为11111111111111111111111110000000,然后再转换成unsigned int,我们知道二进制为11111111111111111111111110000000的unsigned int值为4294967168。见下图:
(4)当unsigned char转换成unsigned int会发生什么呢,也是首先提升为32位,高位全补0。这个比较简单,见下图
在这里做个总结:当小类型提升为大类型时首先提升为大类型的位数(如上面讲的8位提升为32位),然后再把提升后的二进制原封不动的给大类型。提升过程中高位补0还是补1只和小类型的正负有关。如果小类型是unsigned型的,高位一律补0。如果小类型是signed型的,那么看小类型数的符号为是0还是1,如果是0高位就补0,如果是1,高位就都补1。
3.大类型转换成小类型又会发生什么呢。大类型转换成小类型时会被截断,只把大类型的低位给小类型。比如说大类型的二进制为00000000000000000000000110000000(int,384),当把这个值赋给char类型时,不管char是有符号的还是无符号的,都把二进制10000000赋给char,所以当char为有符号的时候值就是-128,当char是无符号的时候就是128。
4.左移和右移。当这个数为无符号数的时候,不管对它进行左移还是右移都补0,如对00000000000000000000000010000000进行左移时得00000000000000000000000100000000,进行右移得00000000000000000000000001000000。当这个数为有符号数时,对它进行左移还是补0,但是对它进行右移就得看情况了。当它是负数时,进行右移就补1,当它是正数时就补0。如对00000000000000000000000010000000进行右移1位得00000000000000000000000001000000,对10000000000000000000000010000000进行右移得11000000000000000000000001000000。
5.进行算数转换时,比int小的如char、short等先按1说的原则转换,再提升为和另一个操作数一样大的类型。见下图