隐式类型转换

前言

  我们在编程中经常进行数值运算,那么你清楚它具体是怎么进行的吗?本期就来带大家深入了解一下计算机进行数值运算的方法。

整形提升的概念

  C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
  这个的意思就是在使用char和short类型时会先进行整形提升,也就是从使用1个字节(char)变成使用4个字节,运算完成之后再进行截断,char只截取一个字节,short截取两个字节。

	char a = 256;
	//0000 0000 0000 0000 0000 0001 0000 0000  一个字节8个bit位
	//截断:0000 0000
	char b = 257;
	//0000 0000 0000 0000 0000 0001 0000 0001
	//截断:0000 0001
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;

在这里插入图片描述

整形提升的意义

  表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
  因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
  通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。

如何进行整形提升

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

//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个bit位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个bit位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0

例一

	char a = 3;
	//0000 0000 0000 0000 0000 0000 0000 0011
	//0000 0011 发生截断

	char b = 127;
	//0000 0000 0000 0000 0000 0000 0111 1111
	//0011 1111 截断

	char c = a + b;
	//先将 a 整形提升:0000 0000 0000 0000 0000 0000 0000 0011
	//再将 b 整形提升:0000 0000 0000 0000 0000 0000 0111 1111
	 
	//c 的值:0000 0000 0000 0000 0000 0000 1000 0010
	//发生截断:1000 0010
	//整形提升:1111 1111 1111 1111 1111 1111 1000 0010 
	printf("%d", c);
	//这里是由%d打印,其实就是将c看成了整型
	//1111 1111 1111 1111 1111 1111 1000 0010 补码
	//1000 0000 0000 0000 0000 0000 0111 1101 反码
	//1000 0000 0000 0000 0000 0000 0111 1100 原码
	//-126

例二

 char a = 0xb6;
 short b = 0xb600;
 int c = 0xb6000000;
 if(a == 0xb6)
 {
 	printf("a");
 }
 if(b == 0xb600)
 {
 	printf("b");
 }
 if(c == 0xb6000000)
 {
 	printf("c");
 }
 return 0;

在这里插入图片描述
  这里的0xb6转化为二进制就是 1011 0110,按照前面整形提升的方法,这是有符号char,前面补符号位,也就是1,结果就是1111 1111 1111 1111 1111 1111 1011 0110,在内存中存储的是补码,要转化为原码来看。

1111 1111 1111 1111 1111 1111 1011 0110 //补码
1000 0000 0000 0000 0000 0000 0100 1001 //反码,符号位不变,其余按位取反
1000 0000 0000 0000 0000 0000 0100 1000 //原码,反码-1
  • 0xb6换成二进制就是
    0000 0000 0000 0000 0000 0000 1011 0110 // 182
  • a的实际存储是
    1000 0000 0000 0000 0000 0000 0100 1000 // -74
  • 两者的数据是不一样的,short同理,只有c是整型,不会发生整型提升,所以最终相等。

例三

	char c = 1;
	char d = 2;
	printf("%u\n", sizeof(c));
	printf("%u\n", sizeof(c+d));
	return 0;

在这里插入图片描述

  • 原因是只要参加了表达式运算,就会发生整型提升,这也是一个证明整型提升的例子。

总结

  因为对这部分内容不太常用,而且我也不太熟悉,所以迟迟未写,恰好今天有空,就去补了一下前面的内容,顺便写出来巩固自己的理解。
  谢谢大家观看,如果有什么不懂的地方可以私信或者评论区留言嗷,觉得不错可以点赞加收藏哦。学习时光阴总是流逝的飞快,那么本期就到此结束,让我们下期再见。

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不如小布.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值