一.整型提升的原因
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
二.整型提升的方法
整形提升是按照变量的数据类型的符号位来提升的
1.对于有符号的整数,高位补充符号位
2.对于无符号的整数,高位补充0
举个例子更好理解
#include<stdio.h>
int main()
{
char a = 5;
char b = 127;
char c = a + b;
printf("%d",c);
}
输出结果:-124;
首先,a中存储的是00000101,b中存储的是011111111,当a,b相加,就会发生整型提升,a为有符号整数,符号位位0,故高位补0,整型提升为00000000 00000000 00000000 00000101,b为有符号整数,符号位为0,故高位补0,整型提升为00000000 00000000 00000000 01111111,两者相加为000000000 000000000 00000000 10000100,又因为c是char类型,故发生截断c中存储的是10000100
同时在printf("%d",c)中,"%d"代表以十进制有符号整数的形式打印,故c要发生整型提升,c为有符号整数,高位补充符号位1,故提升为111111111 11111111 111111111 10000100,要打印就要先转换为原码,将其转换为原码为10000000 00000000 00000000 011111011,计算出值为-124。
3.整型提升的条件
当char,unsigend char,short,unsigned short类型参与了逻辑运算,就会发生整型提升,因逻辑运算是在cpu上进行,整型提升后的数据是存在寄存器上,所以数据会生整型提升。
举个例子:
int main()
{
char c = 1;
printf("%u\t", sizeof(c));
printf("%u\t", sizeof(+c));
printf("%u\t", sizeof(-c));
return 0;
}
输出结果为:1 4 4
因为c前面加了+号和-号,参与了逻辑运算,因此进行了整型提升。
此外,以“%u”,和“%d”的形式打印字符型和短整型也会发生整型提升。
4.练习
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));
return 0;
}
该代码的输出结果是:255
首先,要明白strlen计算的是'\0'(数字0)之前有多少个字符,a的类型为char取值范围是0~127和-128~-1,
进入for循环,a[0]=-1-0=-1,a[1]=-1-1=-2,以此类推a[127]=-1-127=-128,a[128]本来为-1-128=-129,但是超出了其取值范围,要重新计算,-129的原码为10000000 00000000 00000000 10000001
补码为11111111 11111111 11111111 11111111 01111111
a为char类型,要发生截断,故a中存储为01111111,其为正数,原码和补码相同,其值为127
同理a[129]=126,故数组取值是从-1~-128,再从127~0,-1~-128以此类推。
在数字0之前共有255个数字,故输出结果为255。
要注意数字0和字符‘0’的区别。
讲解完毕,如有不足,请指正。