C语言之整型提升
1 有可能出现的问题
代码如下
#include <stdio.h>
int main ()
{
int a = -1;
unsigned int b = 1;
if (a < b) {
printf("a < b");
} else {
printf("a >= b");
}
return 0;
}
运行结果
2 产生以上问题的原因(整型提升)
在表达式计算时,各种整型首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。
**为什么要使用整型提升:**表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。简单来说就是为了在计算中有更快的速度。
3 整型提升的过程
1. 有符号整数的整型提升:高位补充符号位
char var1 = -1;
负数在内存中以补码的形式存储,且char类型占一个字节,即8bit
故变量 var1 的二进制补码为1111 1111
整型提升之后,高位补充符号位1,int为32bit提升后为1111 1111 1111 1111 1111 1111 1111 1111
char var1 = 1;
正数的补码和原码相同,同理可得变量var1的二进制补码为 0000 0001
整型提升之后,高位补充符号位0,提升后为0000 0000 0000 0000 0000 0000 0000 0001
2. 无符号整数的整型提升:高位补0即可
4 整型提升示例
基础知识: 补码的编码规则是:符号位0表示正,1表示负,正数的补码等于原码,负数的补码等于反码末位加1。
#include <stdio.h>
/*
思路:
a补码:1111 1111
b补码:1100 0111
整型提升后(按照32bit):
a补码:1111 1111 1111 1111 1111 1111 1111 1111
b补码:1111 1111 1111 1111 1111 1111 1100 0111
相加之后 == (a + b)补码
1111 1111 1111 1111 1111 1111 1100 0110
转化为原码后
1000 0000 0000 0000 0000 0000 0011 101058
最终打印的值为 -58
*/
int main() {
char a = -1;
char b = 199;
char c = a + b;
printf("%d", c);
return 0;
}
5 总结
在C语言中,当表达式中包含不及int大小的变量时,编译器会自动将其提升为整型,因此需要特别注意这种情况。