以下是在win10_64位+vs2019完成的,不同平台和不同编译器之间可能的结果不同
整型提升是C程序设计语言中的一项规定:在表达式计算时,各种整形首先要提升为int类型,如果int类型不足以表示的话,就需要提升为unsigned int类型,然后再执行表达式的运算。
C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
整型提升的意义: 表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
举例
char a,b,c;
...
a = b + c;
b和c为字符型,大小为1个字节,不满足4个字节大小(int的大小),所以a和b的值会被提升为普通整型,然后再进行加法运算。 运算完成后,再被截断成1个字节(char的大小)存储在a中。
如何进行整体提升
首先要说明的是:C语言标准没有规定char类型是有符号还是无符号,在这些环境下,编译器把char定义为signed char。
规则:按照变量的数据类型的符号位来进行整型提升,无符号整形提升高位补0,有符号整形提升:正数高位补0,负数高位补1。
正数的整型提升
char a = 1;
变量a的二进制位中(补码形式)有8个比特位:
00000001
a是有符号的char类型
所以整型提升时,高位补充符号位,该处a为正数,即为0
提升后的结果为:
00000000000000000000000000000001(32位,整型大小)
负数的整形提升
char b = -1;
变量c1的二进制位(补码形式)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整型提升时,高位补充符号位,该处b为负数,即为1
提升之后的结果为:
11111111111111111111111111111111(32位,整型大小)
无符号整形提升,高位补0
实例
int main()
{
char a = 0xB5;
short b = 0xB500;
int c = 0xB5000000;
if(a==0xB5)
printf("a");
if(b==0xB500)
printf("b");
if(c==0xB5000000)
printf("c");
return 0;
}
实例中的a,b都小于4字节,要进行整形提升,但是c不需要整形提升
a整型提升的过程
0xB5--->10110101
有符号char,最高位为符号位,虽然初始化时是正数,但整型提升时符号位为1,所以前面补1
11111111111111111111111110110101 (补码)
10000000000000000000000001001011 (原码)---> -75
b也是如此,不再赘述。
需要说明的是:整型提升并不会改变数据的值,只是会影响计算过程,这里的a仍为0xB5.
a,b整形提升之后,变成了负数,所以表达式 a==0xb5 , b==0xb500 的结果是假,但是c不发生整形提升,则表 达式 c==0xb5000000 的结果是真。
所以程序输出的结果是: c
本人水平有限,如有错误,请及时指正,谢谢包容。