C语言 | 整型提升你真的了解吗?

C语言的整型算术运算总是至少以默认整型类型的精度来进行的。

为了获得这个精度,表达式中的字符和短整型在使用之前被转换为普通整型,这种转换称为整型提升。

注意,整型提升只针对字符和短整型,并不针对整型和长整型

整型提升的意义:

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般是 int 的字节长度,同时也是CPU的通用寄存器的长度。

因此,两个char类型相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

通用CPU是难以直接实现两个8比特位(也就是1个字节)直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于 int 长度的整型值,都必须先转换为 int 或 unsigned int ,然后才能送入CPU取执行运算。

比如 char 类型,两个8比特位的数相加可能发生进位,如果没有整型提升,进的位可能就丢了,如果整型提升,提升为整型(即32个比特位),计算时的进位不会丢,计算的精度更准确

如何发生整型提升?

整型提升是按照变量的数据类型的符号位来提升的。

有符号数整型提升时高位补充符号位,即整数补 0 ,负数补 1 ;

无符号数整型提升时,高位补 0 。

char c1 = 5;
char c2 = 127;

char c3 = c1 + c2;

printf("%d",c3);

 我们会以为输出结果为132,实则不然。

char c1 = 5;

5 是整型,整型一般是4个字节,所以原反补也是4个字节。

5

原码:0000 0000 0000 0000 0000 0000 0000 0101

由于char 的大小是1个字节,所以 5 存到 char 类型时发生截断,只保留 0000 0101,所以 c1 在内存中存的是 0000 0101

char c2 = 127;

127

原码:0000 0000 0000 0000 0000 0000 0111 1111

同理,c2 在内存中存的是 0111 1111

char c3 = c1 + c2;

c1 和 c2 都是 char 类型,所以相加之前,先整型提升

c1 原本是 0000 0101 ,符号位是 0,所以整型提升时补 0

得到 0000 0000 0000 0000 0000 0000 0000 0101

c2 原本是 0111 1111,符号位是 0,整型提升后得到

0000 0000 0000 0000 0000 0000 0111 1111.

然后这两个数相加,和为 0000 0000 0000 0000 0000 0000 1000 0100,所以 c3 在内存中存的是1000 0100

printf( "%d" , c3 );

%d,意思是以十进制打印有符号整型。

 所以我们需要把 c3 整型提升,提升成整型才能打印。c3 是 1000 0100,且c3 是有符号数,符号位是1,所以整型提升时高位补1,得到 1111 1111 1111 1111 1111 1111 1000 0100,而这是补码,我们需要把它还原为原码。

补码:1111 1111 1111 1111 1111 1111 1000 0100

反码:1111 1111 1111 1111 1111 1111 1000 0011

原码:1000 0000 0000 0000 0000 0000 0111 1100

 最高位为符号位,符号位是1,所以是负数,打印结果为 -124.

 值得注意的是,虽然 c3 被整型提升了,但 c3 仍然是 char 类型,大小依旧是1个字节。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值