1)整型提升
为什么要整型提升?
通常情况下,在对int类型的数值作运算时,CPU的运算速度是最快的。在x86上,32位算术运算的速度比16位算术运算的速度快一倍。C语言是一个注重效率的语言,所以它会作整型提升,使得程序的运行速度尽可能地快。
整型提升是按变量的数据类型的符号位进行提升的。在C语言中,整型算术运算总是⾄少以缺省整型类型的精度来进⾏的。为了获得这个精度,表达式中的字符和短整型操作数在使用前被转换为普通整型,这种转换就叫做整型提升。
对以下代码进行调试
#include <stdio.h>
int main()
{
char a = 3;
char b = 127;
char c = a + b;
printf("%d", c);
return 0;
}
可以发现,返回的结果为-126
在这里结果不为130就是因为进行了整型提升。
2)详解
如果变量a,b为int类型,那结果就是130。但在这里变量a,b以char类型存入,由于字符在内存中所占的字节为1,也就是8个比特位,将数字以char类型存入,在内存中占据的不是int类型一样的32个比特位,而是会被截断,只存入字符大小对应的8个比特位。
一个正数3吧,它以int类型存入时,就是00000000000000000000000000000011。以char类型存入时,就是00000011,只有8个比特位。
接下来讲解char c = a + b是如何运算的
a和b以char型存入内存的,由于a和b都没有达到int类型,这就会发生整型提升,a和b的值被提升为int型,然后再执行加法运算,加法运算完成后,结果将被截断,然后以char型存入c中。
上文已提到
整型提升是按变量的数据类型的符号位进行提升的。
要提升为int类型,先看它的符号位
如果是正数,如3,它以char类型存入时为00000011,要提升为int类型,先看它的符号位为0,这决定了它是负数,那么高位都给它补0,也就是00000000000000000000000000000011 。
如果是负数,如-1,它以char类型存入时为11111111(补码),要提升为int类型,先看它的符号位为1,这决定了它是负数,那么高位都给它补1,也就是11111111111111111111111111111111。
a和b都参与了运算,所以要进行整型提升。因为a和b都为char类型有符号位,提升时补最高位的数字,a和b的最高位都为0 ,所以在最高位前面补0即可,补够32位。
进行整型提升后a、b两者的补码分别为:
00000000000000000000000000000011
00000000000000000000000001111111
将a和b的补码进行相加后得到的补码为:
00000000000000000000000010000010
由于c为char类型,只能存放8个比特位,所以需要截断,计算结果(int型)再赋值给c(char型),截断后c存储为10000010
在进行打印时是以 %d 的形式即int类型打印的,此时需要32位比特位,这时就要对c进行整型提升了。
因为c的最高位是1所以在最高位前面补1补够32位,提升后c的补码补码为11111111111111111111111110000010
将补码转化为原码的形式打印出来,转化后的原码为10000000000000000000000001111110
原码首位是0时为正数,为1时为负数,此原码对应的整数就为-126