C语言之整形提升的有关知识

整型提升的含义

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

我的理解即是:一个整形数据有四个字节,32个比特位,而像字符型或者短整型这种数据,他们不够32个比特位,因此需要提升到32位。

进行整型提升的原因

整型算术运算要在计算机cpu内的整型运算器中进行。而整型运算器的操作数字节长度是整形int的字节长度。所以在整型计算时,要将所有数据提升至整形int的字节长度32位,即4字节。

整型提升的过程

首先我们先来看一串代码:

#include<stdio.h>
int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	char d = 1;
	printf("a=%d,b=%d,c=%d,d=%d", a, b, c,d);
	return 0;
}

再讲解该过程之前,大家先想想输出结果是什么?我猜,有一部分人会认为是-1、-1、-1、1.没错,我在不了解整形提升之前也是这么认为的。
现在我们让代码运行,看看结果是多少:
在这里插入图片描述
咦?为什么会出现255呢?仔细看这里的三个变量都是字符型数据,并不是int,但最终以%d的形式输出,难道出现的255是与整型提升有关吗?
下面我们通过了解整型提升的过程来解开这个疑惑!上面我们仅仅了解到了整型提升的定义和原因,那么到底是如何进行提升的呢
以普通字符型进行举例:

char a = -1;

通过前面的学习我么知道数据在内存中是以补码的形式存储,所以我们先写出变量a的补码:
//原码:10000000000000000000000000000001
通过原码写出反码(符号位不变,其他按位取反)
//反码:11111111111111111111111111111110
通过反码写出补码(反码+1)
//补码:11111111111111111111111111111111
然后进行截断,截断的长度为char的长度,一个字节
得到:11111111
下面进行整型提升:规则是(有符号数据类型,最高位代表符号位,则直接补符号位,无符号数据类型,则直接补0)
这里的char,没说是unsigned char吧?因此我们默认他为有符号数
提升后的结果:11111111111111111111111111111111为该数据的补码
由于它是负数,所以我们需要倒推,通过补码找原码
//反码:11111111111111111111111111111110(补码减一)
//原码:1000000000000000000000000001(符号位不变,按位取反)
输出结果即为-1
以有符号字符为例进行举例:

signed char b = -1;

和上面的分析过程几乎一模一样,只不过这里有符号的特征比较明显,在定义的时候明确指出。
以无符号字符为例进行举例:

unsigned char c = -1

和上面一样我们先写出变量c的补码:
//原码:10000000000000000000000000000001
通过原码写出反码(符号位不变,其他按位取反)
//反码:11111111111111111111111111111110
通过反码写出补码(反码+1)
//补码:11111111111111111111111111111111
然后进行截断,截断的长度为char的长度,一个字节
得到:11111111
注意:这里和上面就不同了,由于它是无符号数据类型,所以补0
提升之后的结果为:00000000000000000000000011111111为该数提升之后的补码,由于它是无符号数据类型,因此最高位并不代表符号位,所以它的原码反码补码相同。
输出结果为255
以正数为例进行举例:

char d = 1;

和上面一样我们先写出变量d的补码:由于该数为正数所以它的原码反码补码相同
//原码/反码/补码:00000000000000000000000000000001
然后进行截断,截断的长度为char的长度,一个字节
得到:00000001下面进行整型提升:这里的char,没说是unsigned char吧?因此我们默认他为有符号数提升后的结果:00000000000000000000000000000001为该数据的补码,由于该数为正数所以它的原码反码补码相同
输出结果为1

short类型进行整型提升的时候是如何进行的?

其实它的步骤和char基本相同,差别在于,截断过程,char类型截断8个比特位,因为它是一个字节,而short截断16个比特位,因为它是2个字节。
下面通过具体的示例进行演示:

unsigned short c = -1;

和上面一样我们先写出变量c的补码:
//原码:10000000000000000000000000000001
通过原码写出反码(符号位不变,其他按位取反)
//反码:11111111111111111111111111111110
通过反码写出补码(反码+1)
//补码:11111111111111111111111111111111
然后进行截断,截断的长度为short的长度,两个字节
得到:1111111111111111
注意:由于它是无符号数据类型,所以补0
提升之后的结果为:00000000000000001111111111111111为该数提升之后的补码,由于它是无符号数据类型,因此最高位并不代表符号位,所以它的原码反码补码相同。
输出结果为65535
其他的signedshort和short也是类似的步骤和方法,这里就不过多赘述了。

那整型提升会在哪里用到呢?

还是用上面的变量举例,当字符型数据进行整形运算时,不能直接进行代数和的相加减乘除,必须先进行整型提升,之后再进行代数和的相加减乘除。
以char为例进行举例:

#include<stdio.h>
int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	char d = 1;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c,d);
	printf("a+b=%d\na+c=%d\na+d=%d\nb+c=%d\nb+d=%d\nc+d=%d\n",a+b, a + c,a+d,b+c,b+d,c+d);
	return 0;
}

输出结果如下所示:
在这里插入图片描述
以short为例进行举例:

#include<stdio.h>
int main()
{
	short a = -1;
	signed short b = -1;
	unsigned short c = -1;
	short d = 1;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c,d);
	printf("a*b=%d\na+c=%d\na+d=%d\nb+c=%d\nb+d=%d\nc+d=%d\n",a*b, a + c,a+d,b+c,b+d,c+d);
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从未止步..

谢谢你的打赏,我会继续努力!

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

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

打赏作者

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

抵扣说明:

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

余额充值