整形提升
1.是什么?
定义:C语言的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。 通俗讲:C语言中字节数少于整型字节数的数据类型在进行整型运算时,该类型的数据会被默认转为整型数据。
2.为什么要?
CPU整形运算器(ALU)操作字节长度决定。
表达式的整形运算在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是 int 的字节长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
3.提升规则 将少于4个字节的数据变成4个字节的数据
- 如果是无符号数,则高位直接补0;
- 如果是有符号数,则高位全补符号位。
正数整形提升:高位补充符号位0。负数的整形提升:高位补充符号位1 例如 char c= -1; 10000000 00000000 00000000 00000001 原码 11111111 11111111 11111111 11111110 反码 11111111 11111111 11111111 11111111 补码(-1在内存中的存储形式) char占1个字节 11111111 有符号数 11111111 11111111 11111111 11111111(整形提升) 4.什么时候进行(整形运算) 注意:char,short等数据在存储是,没有整形提升。发生这个整型提升的前提是它们参与整型运算!而且整型运算结束后,4个字节的数据将发生截断,再返回值。也就是说,运算完成后,CPU返回值的字节数仍为这个数据原本类型的字节数,而不是提升后的字节数。截断的规则是留低位弃高位。 来道题说明一下:
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a==0xb6)
printf("a");
16进制表示
printf("b");
if(c==0xb6000000)
printf("c");
return 0;
}
首先公布结果 c 接下来进行分析:char a = 0xb6;数据赋值发生整形提升吗?no。默念整形运算时发生。 if(a==0xb6)?? 发生,出现了运算。==左边的a是char型,有符号数,发生整形提升
-
if(a==0xb6); 左边的a是char型 00000000 00000000 00000000 10110110(b6内存中的存储形式) 10110110(截断) 11111111 11111111 11111111 10110110 (提升) 16进制表示0xffffffb6 右边的0x6b是字符常量,有符号数, 16进制表示0x000000b6 不相等,故不打印。 -
short b = 0xb600; 左边的b是short型,所以b是有符号数,发生整型提升,b为0xffffb600 右边的0xb6是字面常量,是有符号数,写完整是0x0000b600 不相等 -
if(c==0xb6000000) c是int,右边4个字节,不需要提升。
来个题瞅瞅
int main()
{
unsigned char a = 200;
unsigned char b = 100;
unsigned char c = 0;
c = a + b;
printf("%d %d",a+b,c);
return 0;
}
-
usigned char 0-255 200,100储存到a和b中发生截断 200在内存 的存储 00000000000000000000000011001000(4个字节)
放到unsigned char a里面 11001000 (截断,一个字节)
100在内存 的存储00000000000000000000000001100100
放到unsigned char b里面 01100100
-
进行计算+时,两个操作数达不到整形大小时,要进行整形提升,unsigned char a,b无符号数进行提升时,高位直接补0即可。 整形提升后的: 00000000000000000000000011001000-a 00000000000000000000000001100100-b 计算 00000000000000000000000100101100-a+b a+b的结果没有放到c里面去,就没有发生截断,直接以%d的形式打印出来。直接将结果打印出来,300 -
c=a+b %d打印的是有符号数,它看到内存中的c是个char,要整形提升。认为内存中放的是补码,要得到原码打印出来。 c需要将00000000000000000000000100101100-a+b截断成0101100,然后进行整形提升(补0) 00000000000000000000000000101100,经过补码-反码-原码的转换(正数原反补相同),打印 44
参考
1.C语言整型提升的规则及样例详解https://blog.csdn.net/m0_56311933/article/details/119699918 2.整型提升 https://blog.csdn.net/qq_39208237/article/details/109503755
|