整型提升~

整型提升

什么是整型提升?

首先,我们应该知道这一点:C语言中整型运算总是至少缺省整型类型的精度来进行的。

这句话什么意思呢?用大白话说就是:C语言中字节数少于整型字节数的数据类型在进行整型运算时,该类型的数据会被默认转为整型数据。

其中,该类型的数据被转化为整型数据的过程就称为整型提升

为什么要进行整型提升?

为什么会发生整型提升呢?这是由计算机体系结构决定的,我们都知道计算机中的计算都由CPU完成,具体来说是由CPU中的运算器(ALU)完成的。而ALU一般在被设计时,其操作对象——操作数的字节大小被要求至少是int的字节数。此时,我们还要明晰一个事情,那就是数据在被运算时,数据并不是直接在ALU上存储的,而是存储在CPU的寄存器(register)中,而通用寄存器的字节大小与ALU操作数的字节大小保持一致。

这又怎样?空间大又不是不能存储字节数少的数据。是的,话没错,能存,但问题在于我是4个字节的空间(大房间里有四个小房子),你是少于4个字节的数据(不能完全占据整个大房间),我到底该把你安排在哪个小房间里?我把你随便放进去的话,我要用你时又要在4个小房间里查找你到底在哪些房间里,这样势必会让我的效率变低。所以,你在住进来时,不好意思,你至少得把自己变成4个字节的,我再把你直接放进去,用你时我也不用查你在哪,我找到大房间就找到了你。

可能这会有人会问,那我多于4个字节怎么办?不要担心,你多于4个字节,大不了我给你再安排一间大房子,你一个人住两间总该够了。在64位平台,C语言非自定义数据类型的字节数只有4种(1,2,4,8)。两间大房子妥妥把你舒舒服服住好喽!

再看非自定义数据类型的字节数取值可能,我们发现只有(1,2)在进行整型运算时,会发生整型提升。而这两个数据类型对应的便是charshort

说来说去,我们一句话就可以给它总结了:C语言中,表达式中的字符和短整型操作数在使用之前会发生整形提升,变为普通整型

再来回顾一下问题:为什么要进行整型提升?这是由计算机体系结构决定的!

怎么进行整型提升?

大白话:怎么将少于4个字节的数据变成4个字节的数据?

规则!规则!规则!:整型提升是按照变量的类型来进行提升的。具体点如下:

a. 如果是无符号数,则高位直接补0;
b. 如果是有符号数,则高位全补符号位。

对!你没有看错,我也没有说错,就这么两句话!

举个栗子:

声明一点:任何数据在计算机中进行存储时,都是它的二进制形态,再精确点就是以补码形态进行存储。

char c = -1;

c变量的空间里存储着-1的补码(1111 1111),因为char只有一个字节,所以仅有8个比特位。
这个char定义时没说unsigned char吧?所以此char有符号char.
那它在进行整型提升时,用规则b。(1111 1111)被char修饰为有符号数,所以它的最高位为符号位!符号位为1,则它进行整型提升时,高位补3个字节的1。
即(1111 1111 1111 1111 1111 1111 1111 1111

再来看第二个栗子:

char c = 1;

c变量的空间里存储着1的补码(0000 0001),因为char只有一个字节,所以仅有8个比特位。
这个char定义时没说unsigned char吧?所以此char有符号char.
那它在进行整型提升时,用规则b。(0000 0001)被char修饰为有符号数,所以它的最高位为符号位!符号位为0,则它进行整型提升时,高位补3个字节的0。
那我对你进行整型提升时,高位补2个字节的0就就行了。
即(0000 0000 0000 0000 0000 0000 0000 0001

再来看栗子:

unsigned short a = -1;

a变量的空间里存储着-1的补码(1111 1111 1111 1111),因为short有两个字节,所以有16个比特位。
这个short定义时说了unsigned short吧?所以此short无符号short.
那它在进行整型提升时,用规则a。我管你原来是什么数!现在我就知道你是无符号数!
那我对你进行整型提升时,我只管高位补2个字节的0就行了。
即(0000 0000 0000 0000 1111 1111 1111 1111
今天就是天王老子来了,只要你是无符号数!我照样只管高位补0,把你补成4个字节就行。

注意注意!注意!

不要觉得charshort在存储时,就发生了整型提升!发生这个整型提升的前提是它们参与整型运算!!而且整型运算结束后,4个字节的数据将发生截断,再返回值。也就是说,运算完成后,CPU返回值的字节数仍为这个数据原本类型的字节数,而不是提升后的字节数。截断的规则是留低位弃高位。

理解没理解的关键在于你现在知道整型提升的数据在哪存着吗?

CPU的寄存器!!!!!寄存器!

你懂了?上道例题考察你一下!

int main()
{
	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;
}

你猜程序打印结果是啥?

abc? ab? ac? bc? b? c?

容我问一句!==在哪里进行?它是逻辑运算,在CPU上进行,所以左右两边的数据在哪?对!寄存器register! 所以数据要不要发生整型提升?要的!

咱们来剖析一下代码

if(a==0xb6)

==左边的a是char型,所以a是有符号数,发生整型提升,a为0xffffffb6;
==左边的0xb6是字面常量,是有符号数,写完整是0x000000b6
相等吗?不相等!条件不成立,不打印!

if(b==0xb600)

==左边的b是short型,所以b是有符号数,发生整型提升,b为0xffffb600;
==左边的0xb6是字面常量,是有符号数,写完整是0x0000b600
相等吗?不相等!条件不成立,不打印!

if(c==0xb6000000)

==左边的c是int型,右边4个字节数,要发生整型提升吗?不要!
条件成立。
所以程序运行结果就是 c
result

嘿嘿嘿

懂了?
来,思考一下,结果是啥

	char a = 255;
	unsigned char b = -1;

	printf("a = %u\n", a);
	printf("b = %u\n", b);

result2
再送一句话:
初始化或赋值时只关心该变量提供的空间;
提取内容时要先看数据的类型。

第一句话:不管你定义啥类型变量,我只需要等号右边数据的补码放进你的空间就行
第二句话:当你要用这个变量时,要先看该变量的定义类型,再看需不需要整型提升,需要的话,怎么提升,提升完了再看读取这个数据的类型。
result3

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值