【C语言】整型提升(隐式类型转换)

         本文将会介绍C语言中的隐式的整型提升

一、什么是整型提升

         在C中是存在隐式类型转换的,就是在C中的整型算数运算总是至少以缺省整型类型的精度来进行相关操作,为了获得这个精度,表达式中的字符和短整型都必须要转化为普通整型。

二、为什么需要整型提升

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

三、如何进行整型提升

以下操作在windows vs2019  x86环境下进行

不妨先看一下这段代码:

int main()
{
	char a, b, c;
	a = 1, b = 127;
	c = a + b;
	printf("%d", c);
	return 0;
}

按照常理,c应该是128,但是结果如下:

这是因为:

1(10进制)    =00000000 00000000 00000000 00000001(二进制补码)

127(10进制)=00000000 00000000 00000000 01111111 (二进制补码)

但是由于a和b默认是signed char类型的数,表示是有符号的字符类型,由于char类型的变量大小为一个字节,即八位,并且最高位表示的是符号位(0为正,1为负),所以表示的最大的正数是01111111=127。所以a和b在赋值的时候就会进行截断,只会赋值的最低的八位。所以:

a=00000001

b=01111111

运算时就会进行整型提升,由于a和b的最高位是0,所以在a和b的高位补0:

a=00000000 00000000 00000000 00000001

b=00000000 00000000 00000000 01111111

运算结果为00000000 00000000 00000000 10000000

由于c为char类型,会发生截断,只会取低八位:

c=10000000

c的的最高位为1,所以会c的整型提升操作是在c的高位补1,如下:

c=11111111 11111111 11111111 10000000(补码)

然后转化为原码:

c=10000000 00000000 00000000 10000000(原码)

此时c的最高位为符号位,为1,即是负数,10000000=128,所以结果会输出-128。

整型提升是C语言中的隐式类型转换,C语言中还包括其他的类型转换,下面是另外的一种隐式类型转换:

下面是另外的一道例题:

#include <stdio.h>
int main() {
	int n = 4;
	n -= 5;
	if (n > sizeof(n))
		printf("1\n");
	if (n < sizeof(n))
		printf("2\n");
	return 0;
}

如果没有心机的看,n-=5后n应该等于-1,而sizeof(n)应该等于4,按理说应该输出1,但是结果如下:

 是不是突然觉得发现C的bug了,其实不然,这就是C中整型提升不知道坑了多少人的实例。

现在就讲解一下为什么会得到输出1的:

在本环境中中int 默认是signed int(不同编译环境下默认是不同的)

-1=11111111 11111111 11111111 11111111(补码,最高位是符号位)

由于sizeof()的返回值是size_t,是unsigned int类型的数

此时C中有一个原则:小的往大的扩展。标准转换的规则是:短的的向长的转;有符号的向无符号的转。所以在n和sizeof(n)进行比较的时候会将n的signed int转化为unsigned int 类型,此时n的最高位就不再是符号位而是数值位,所以此时c=4294967295,这个数会远远大于4或8。所以输出结果是1。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值