变量的整型提升和截断

变量的整型提升和截断

什么是整型提升?

在 CPU 运算时,为了方便 CPU 的运算,(一般情况下)把字节长度不足 int 类型长度的变量类型(例如:cahr short)先转换为至少为 int 类型的类型长度进行计算,这个过程叫做 整型提升

什么是截断

截断是指当将较大类型的数据存储到较小的数据类型变量中时,多余的位会被去掉,导致信息丢失。

接下来我将用一个简单的小程序,同时说明整型提升和截断之间的关联
因为截断时需要判断最高位是 0 还是 1,以便来判断一个变量的正负
所以首先要说明一些别的东西:

什么是原码、反码和补码
例如现在有一个十进制数 10 吧,把它转换成 8 位的二进制编码,
也就是:0000 1010

它就是一个原码:0000 1010
反码就是把这 8 位二进制编码按位取反
也就是: 1111 0101
而一个原码的补码就是原码的反码 + 1
也就是: 1111 0110

知道了原码、反码和补码,这个时候就可以告诉你,变量在程序里储存的时候,正数用的是原码,负数用的是补码,最高位是符号位(0正 1负)
例如:

char a = 10;
char b = -10;
char 在内存中占的是一个字节,也就是 8 位,
此时 a 在内存中用二进制表示为: 0000 1010
此时 b 在内存中用二进制表示为: 1111 0110 (这个位置用了原码转补码的规则)

也就是说如果这个例子中的 ab 相加,假如它的最高位是 1 ,那么它里面放的就是负数,运用的就是补码的规则,而补码想要得到原码就需要这样

现在有一个补码是 : 1111 0110
我先让它 -1 得到它原码的反码: 1111 0101
在对它取反就可以得到它的原码了:0000 1010
聪明的小伙伴可能已经发现了这就是 -10 推导到 10 的过程,而上面的例子是从 10 推导到 -10 的过程

知道了如何判断一个变量用的是原码还是补码就可以判断出一个被截断的变量的值。
变量的整型提升高位补的是符号位,也就是说:

char a = 10;
char b = -10;
int c = a + b;//这个时候由于 ab 的长度都不足 int 类型的长度,这里发生了整型提升

a没有整型提升前 在内存中用二进制表示为: 0000 1010
b 没有整型提升前在内存中用二进制表示为: 1111 0110

由于整型提升高位补符号位

此时 a 在内存中二进制表示为:
00000000 00000000 00000000 00001010
此时 b 在内存中二进制表示为:
11111111 11111111 11111111 11110110

好下面例子来了
示例 :

#include <stdio.h>
int main() 
{
	char a = 127;
	// 127 的二进制编码 0111 1111
	char b = 3;
	// 3 的二进制编码   0000 0011
	char c = a + b;//把 a + b 的值赋给 c
	//char 类型不满足 int 类型的长度,整型提升得出
	// 127 
	//0000 0000 0000 0000 0000 0000 0111 1111
	// 3
	//0000 0000 0000 0000 0000 0000 0000 0011
	// 故 a + b 的值为
	//0000 0000 0000 0000 0000 0000 1000 0010
	//这里以为 c 是 char 类型的变量,所以发生了截断 c,取低八位也就是 1000 0010
	//取完低八位后,截断之后的值是 1000 0010,注意这里的最高位是 1,也就是说它是一个负数
	//它服从补码的规则
	//1000 0010 ->补码
	//1000 0001 ->反码
	//0111 1110 ->原码	126
	//所以这个是有符号的	126
	//即 -126
	printf("%d", c);
	return 0;
}

运行结果
在这里插入图片描述跟上面注释分析的是一样的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值