C语言中的整型提升

476 阅读4分钟

以下是在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

本人水平有限,如有错误,请及时指正,谢谢包容。