整型提升

待到秋来九月八,我花开尽百花杀

我们在使用表达式求值的顺序一部分是由操作符的优先级和结合性决定的。
同样,有一部分表达式的操作数在求值的过程中可能需要转换为其他类型。

隐式类型转换

C语言中的整形算术运算总是以缺省整形类型的精度来进行运算的。
比如
char a,b,c;
a = b + c;
在计算过程中,b,c的计算结果是整型,计算之后的值,将会取得char类型所需要的bit位数,其他位被省略。

为了获得这个精度,表达式中的字符和短整型等其它类型的操作数在使用之前被转换成为普通int或unsigned int整型,这种转换称为隐式类型转换,即整型提升。

整型提升的意义

表达式的整形运算要在CPU相应的运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般是int的字节长度,同时也是CPU的通用寄存器的长度——32bit。

因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度32bit。

通用CPU(general-purpose CPU)是难以直接实现两个8bit直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以表达式中各种长度可能小于int长度的整型值,都必须先转换成int或unsigned int,然后才能送入CPU去执行运算。

例如:
char a,b,c;
a = b + c;
b和c的值被提升为int整型,然后再执行加法运算。
加法运算完成后,结果被截断,然后存储在a中。
在这里插入图片描述

如何进行整型提升?

整型提升我们可以简单的分为两个步骤进行:
第一步:
查看所要整型提升的变量的原类型是什么?
第二步:
如果是无符号类型的整型提升,高位补0直到补足32位
如果是有符号类型的整型提升,看最高位(也就是符号位)是什么,如果是0高位补0直到补足32位,如果是1高位补1直到补足32位。

例如:
复数的整型提升:
char a = -1;
变量a在计算机中的二进制储存为1111 1111
因为char为有符号字符类型
所以整型提升的时候,高位补充符号位,即为1。
提升之后的结果是:
1111 1111 1111 1111 1111 1111 1111 1111

正数的整型提升
char a = 1;
变量a在计算机中的二进制储存为:0000 0001
因为char为有符号字符类型
所以整型提升的时候,高位补充符号位,即为0。
提升之后的结果是:
0000 0000 0000 0000 0000 0000 0000 0001

无符号整型提升与正数的整型提升相同。

实例

我们可以查看几个实例以证明计算机用到了整型提升

#include<stdio.h>
int main()
{
    
    
 char a = 0xb6;//0xb6为16进制的182
 short b = 0xb600;
 int c = 0xb6000000;
 if(a == 0xb6)
 printf("a\n");
 if(b == 0xb600)
 printf("b\n");
 if(c == 0xb6000000)
 printf("c\n");
 printf("%u", a);
 printf("%d\n", a);
 system("pause");
 return 0;
}

在这里插入图片描述
说明上例中a,b要进行整型提升,但是c本身比特位满足CPU计算要求不需要整型提升,而a,b整型提升之后被CPU计算后返回的数识别为了负数(例如a被识别为了-74)自然不满足a == 0xb6的条件,结果为假,而c没有进行整型提升,判断结果为真。

#include<stdio.h>
int main()
{
    
    
 char c = 1;
 printf("%u\n", sizeof(c));
 printf("%u\n", sizeof(+c));
 printf("%u\n", sizeof(-c));
 printf("%u\n", sizeof(!c));
 system("pause");
 return 0;
}

在这里插入图片描述
我们可以看到,变量c只要参与了需要通过CPU的运算,就一定会发生整型提升,所以sizeof©没有通过CPU运算,不需要整型提升就是原本的char类型,也就是1字节,而其他三种都是4字节,执行了整型提升。
注意:!c,也进行了整型提升,不过在windows下被特殊处理了,使用Linux运行后可以发现仍然是4字节。
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40893595/article/details/104441826