C语言整形提升举例详解
Jambo! 人气:01.什么是整形提升
表达式中的字符和短整形操作数在使用之前被转换成普通整形
int
,这种转换叫做整形提升
整形提升针对的类型小于整形的
char
,short
char
占用1字节空间,short
占用2字节空间,在运算时都会提升为占用4个字节的int
类型
所以C的整型算术运算总是至少以缺省整型类型的精度来进行的。换而言之整形算术运算都至少以int
类型计算的
2.为什么会有整形提升
表达式的整形运算要在CPU的相应运算器内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
因此,即使两个char
类型的变量相加,在·CPU执行时实际上也要先转化为CPU内整型操作数的标准长速度。
3.如何进行整形提升呢?
整形提升是按照变量的数据类型的符号位来提升的
负数的整形提升:
char c1 = -1
,char
类型占1字节,也就是它的二进制补码只有8个比特位 :1111111
因为char
是有符号位的char
,所以整形提升的时候,高位补符号位1
提升之后的效果为:11111111111111111111111111111111
正数的整形提升:
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:00000001
因为char
为有符号的char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:00000000000000000000000000000001
无符号的整形提升:高位补0
4.整形提升的例子
例1
#include<stdio.h> int main() { char a = 3; char b = 127; char c = a + b; printf("%d\n", c); return 0; }
char a = 3
,首先把3
放到a
中,3是int
类型,3的二进制序列为:00000000000000000000000000000011
需要把3
放到char
中,int
是32个比特位,char
是8个比特位,所以接下来需要进行截断:将低8个比特位放到char
中,所以此时a
中为:00000011
char b = 127
也是一样127
为00000000000000000000000001111111
截断为011111111
char c = a + b
,接下来要进行整型提升
当前char
为有符号的char
,所以对于a
就高位补0
,为:00000000000000000000000000000011
同理,b
整形提升后为:00000000000000000000000001111111
接下来相加为
00000000000000000000000010000010
,将这个32位二进制放到c
中,截断为10000010
printf("%d\n", c)
中,%d
是打印十进制的数,所以还需整形提升,此时c
为10000010
,符号位为:1
,整形提升高位补1
,最终为11111111111111111111111110000010
(补码),其原码为10000000000000000000000001111110
,所以这个数字输出为-126
输出结果:
例2
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; }
比较也是表达式,
a
,b
也要发生整形提升,所以只有c
不会整形提升,所以输为c
输出结果
这个例子能体现整形提升的存在
例3
int main() { char c = 1; printf("%u\n", sizeof(c)); printf("%u\n", sizeof(+c)); printf("%u\n", sizeof(-c)); return 0; }
c
是char
类型,sizeof(c)
值为1+c
.-c
中,c
都参与计算,所以整形提升为int
类型,sizeof(+c)
,sizeof(-c)
值都为4
输出结果:
这个例子也能体现整形提升的存在
例4
下面程序输出什么?
#include <stdio.h> int main() { char a = -128; printf("%u\n",a); return 0; }
- 10000000000000000000000010000000 -128原码
- 11111111111111111111111101111111 -128反码
- 11111111111111111111111110000000 -128补码
- 截断 10000000 a
- 整形提升11111111111111111111111110000000
- 所以最后输出11111111111111111111111110000000对应的十进制数,是一个很大的数
例5
下面程序输出什么?
#include <stdio.h> int main() { char a = 128; printf("%u\n",a); return 0; }
10000000000000000000000010000000
128补码- 截断:
10000000
a补码 - 整形提升:
11111111111111111111111110000000
- 所以最后输出
11111111111111111111111110000000
对应的数,一个很大的数
整形提升是真实存在的,但是我们平时感觉不到他的存在
其他操作符如int
,float
,double
等大于等于int
的操作符,之间的转换,就要用到算术转换了
总结
加载全部内容