一.整型提升
1.什么是整形提升
表达式中的字符和短整形操作数在使用之前被转换成普通整形int,这种转换叫做整形提升
整形提升针对的类型小于整形的char,short
char占用1字节空间,short占用2字节空间,在运算时都会提升为占用4个字节的int类型
所以C的整型算术运算总是至少以缺省整型类型的精度来进行的。换而言之整形算术运算都至少以int类型计算的
2.正数的整形提升:
(1)char a = -1,char类型占1字节
-1的原码为
10000000 00000000 00000000 00000001
反码为
111111111 111111111 111111111 111111110
补码为
111111111 111111111 111111111 111111111
但是要改为char类型 所以只留8个bit位
也就是它的二进制补码只有8个比特位 :1111111
因为char是有符号位的char,所以整形提升的时候
高位补符号位1
提升之后的效果为:11111111111111111111111111111111
然后补码基础上得到反码(通过-1实现)
11111111111111111111111111111110
然后按位取反得到int类型原码
10000000 00000000 00000000 00000001
a
所以a=-1;
(2)char b = 1;
由于1的原反补码均为
10000000 00000000 00000000 00000001
由于转换char类型,变量b的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
提升之后,原反补均为
00000000000000000000000000000001
所以b为1
通过(2)得出如果char和short类型 转换的数字小于128,则变量不变!!!
举例说明:
a小于128,所以即使发生整形提升 也并未对其造成改变
b为16进制数 大于128,所以发生整形提升后 转换char或short时,截断发生数量丢失,所以对其改变
c即使大于128,但是c为int类型所以不变
d为十进制,大于128,与b原理一样 截断数量丢失,则对其改变
所以结果只有a,c。
3.整形提升的例子:
(1)
char a = 3,首先把3放到a中,3是int类型,3的二进制序列为:
00000000000000000000000000000011
需要把3放到char中,正数原反补码又一样,int是32个比特位,char是8个比特位,所以接下来需要进行截断:将低8个比特位放到char中,所以此时a中为:
00000011
char b = 127也是一样
127为00000000000000000000000001111111
截断为011111111
char c = a + b,接下来要进行整型提升
当前char为有符号的char,所以对于a就高位补0,为:
00000000000000000000000000000011
同理,b整形提升后为:
00000000000000000000000001111111
接下来相加为
00000000000000000000000010000010
将这个32位二进制放到c中,截断为
10000010
printf("%d\n", c)中,%d是打印十进制的数,所以还需整形提升,此时c为10000010
符号位为:1
整形提升高位补1,最终为
11111111111111111111111110000010(补码)
其原码为
10000000000000000000000001111110
所以这个数字输出为-126
(2)
如果sizeof里面没有出现运算,则sizeof结果为1
若发生运算,则sizeof会默认为整形提升 char转换为int,所以sizeof结果为4
但是为什么c++、c--的结果为1呢
我们先暂时默认为一。
(3)unsigned 无符号类型题:
(4)
-128原码
10000000000000000000000010000000
-128反码
11111111111111111111111101111111
-128补码
11111111111111111111111110000000
截断
10000000
尽管printf后为u,但是char是有符号位的
整形提升:
11111111111111111111111110000000
由于u输出为无符号整数,不管提升之后为正负,所以原反补不变
所以最后输出
11111111111111111111111110000000
对应的十进制数,是一个很大的数
所以看清printf后是%d还是%u!!!
(5)
和(4)的原理一样
对应的十进制数,是一个很大的数
(6)char为-128~127的来源
unsigned char 为0~255
以下为short 和 unsigned short
整形提升是真实存在的,但是我们平时感觉不到他的存在
其他操作符如int
,float
,double
等大于等于int
的操作符,之间的转换,就要用到算术转换了
二.算数运算
如果一个操作符的各个操作数属于不同的类型,那么其中某些操作数必须转换为其他操作数类型,否则无法进行计算。
转换规则:
- 小于int类型的先进行整形提升
- 排名低的向排名高的转换(如下图)
a/b,因为a和b都是int 类型,不需要进行提升,所以a/b的结果被认为还是int 类型,是int 类型就只会截取整数部分,所以c里面存的就是0。