c语言表达式求值--整型提升

什么是整型提升?

C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

什么叫缺省整数类型?缺省在计算机里面是默认的意思。

这句话大概意思就是,在c语言的整数运算中,如果有精度小于整型的非自定义类型数,就需要先转换为一个整数类型。

比如char和short int类型,它们的字节数分别为1、2,如果它们参与整数表达式的运算就会先转换成整数类型,再参与运算。

这里我们只谈论char和short int

代码举例:

int main()
{
	char a = 0x80;
	short b = 0x8000;
	int c = 0x86000000;
	if (a == 0x80)
		printf("a");
	if (b == 0x8000)
		printf("b");
	if (c == 0x86000000)
		printf("c");
	return 0;
}

看结果:

0d54d9484a714f45bd0b199538fb437f.png只输出了一个c。

为什么会这样呢?a、b变量被赋予的值也没有超出它们的字节大小代表的最大值,为什么a==0x80和b==0x8000会为假呢?

这其中就发生了整型提升。

 

整型提升的规则

1、操作数为int的时候,高位补充符号位

2、操作数为unsigned int(无符号整数)的时候,高位补充0

 分析例子

1.变量a整型提升:

首先,a占一个字节,在转换前被赋值0x80(十六进制),二进制(补码)表示为1000 0000。

符号位是1.

整型提升变成四个字节,前面补充1,就转换成了:

1111 1111 1111 1111 1111 1111 1000 0000

所以这个时候的a就不等于原来的数了,很明显这都变成了一个负数。

2.变量b整型提升:

首先,b占两个字节,在转换前被赋值0x8000(十六进制),二进制(补码)表示为:

1000 0000 0000 0000

符号位是1.

整型提升变成四个字节,前面补充1,就转换成了:

1111 1111 1111 1111 1000 0000 0000 0000

所以这个时候的b就不等于原来的数了,很明显这都变成了一个负数。

而c是int,不需要转换。

代码1:


int main() {
	char a = 0x80;
	char b = 0x80;
	int c = a + b;
	printf("%d", c);

	return 0;
}

这里又会输出什么结果呢?

因为运算涉及到整数,所以字符a和b在参与计算的时候会先整数提升,而根据上面我们知道,a整型提升之后是一个负数,所以得到:

edeec9cb8fed4fedbedfe75677c67981.png

 

代码2:

int main()
{
 char c = 1;
 printf("%u\n", sizeof(c));
 printf("%u\n", sizeof(+c));
 printf("%u\n", sizeof(-c));
 return 0;
}

这里我们要注意,我前面已经强调过,只有在参与运算的时候才会考虑是否要整型提升,而sizeof(c)里的c并没有参与运算,所以不需要整型提升,得到的还是一个字节。

那么sizeof(+c)和sizeof(-c)呢?c语言会认为(+c)和(-c)都是参与了运算,所以需要整型提升,得到的也就是一个整型的字节大小。

1a2e9b63568d46a69bc44b9d61712b7c.png

 

整型提升的意义?

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

总的来说,整型提升的目的是为了保持表达式中操作数的一致性。当不同大小的整数类型参与运算时,较小的类型会被提升为较大的类型,以避免精度丢失和数据溢出的问题

 

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值