目录
整型提升是什么?为什么要整型提升?
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换成CPU内整型操作数的标准长度。通用CPU是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加的指令)。所以,表达式中各种长度小于int长度的整形值,都必须先转换成int或unsigned int,然后才能送入CPU去执行运算。
整型提升的注意点
负数的整形提升,高位补1(补符号位)
正数的整形提升,高位补0(补符号位)
无符号数整型提升时,高位补0
代码与例题
例一:
#include<stdio.h>
int main()
{
//char——>unsigned char(有符号dchar)
char a = 3;
//四个字节的数据非要放到1个字节的空间里面叫做截断
//00000000000000000000000000000011(32个比特位)
//00000011->a(只能存放8个比特位到a里)
char b = 127;
//00000000000000000000000001111111
//01111111->b
char c = a + b;
//整形提升
//00000000000000000000000000000011//最高位的符号位是“0”,就补“0”
//00000000000000000000000001111111
//00000000000000000000000010000010//相加后
//10000010->c//截断
printf("%d\n", c);
//%d打印十进制的整数
//还是要继续整型提升
//11111111111111111111111110000010——补码//最高位的符号位是“1”,就补“1”
//11111111111111111111111110000001(减一)
//00000000000000000000000001111110(取反)——原码
//-126
return 0;
}
例二:
#include<stdio.h>
int main()
{char a=-1;
//10000000000000000000000000000001——原码
//11111111111111111111111111111110——反码
//11111111111111111111111111111111——补码
//11111111——截断
printf("%d",a);
//整型提升,补最高位
//11111111111111111111111111111111——原码
//10000000000000000000000000000001——补码
//打印出来是-1
return 0;
}
例三:
#include<stdio.h>
int main()
{
char a = -1;
//10000000000000000000000000000001——原码
//11111111111111111111111111111110——反码
//11111111111111111111111111111111——补码
//放到char里面要截断
//11111111
//printf打印%d时,要整型提升
//有符号数补符号位
//11111111111111111111111111111111——补码
//10000000000000000000000000000001——原码
//所以a打出来是-1
signed char b = -1;
//在vs里面char就是signed char
//所以b打出来也是-1
unsigned char c = -1;
//10000000000000000000000000000001——原码
//11111111111111111111111111111110——反码
//11111111111111111111111111111111——补码
//放到char里面要截断
//11111111
//printf打印%d时,要整型提升
//无符号数补0
//00000000000000000000000011111111——补码
//00000000000000000000000011111111——反码
//00000000000000000000000011111111——原码
printf("a=%d,b=%d,c=%d", a, b, c);
return 0;
}
例四:
#include<stdio.h>
int main()
{
char a = -128;
//10000000000000000000000010000000——原码
//11111111111111111111111101111111——反码
//11111111111111111111111110000000——补码
//10000000截断
//11111111111111111111111110000000——补码、反码、补码
printf("%u\n", a);
return 0;
}