1.整形提升
提升是将占字节小的元素赋给占字节大的元素时出现的补位现象。
截断是将所占字节大的元素赋给所占字节小的元素时会出现数值的舍去现象;
下面看代码来分析:
#include <stdio.h>
int main()
{
char a= -1;
// 原:1000 0001
//反:1111 1110
//补:1111 1111
signed char b=-1;
// 原:1000 0001
//反:1111 1110
//补:1111 1111
unsigned char c=-1;
// 原:1000 0001
//反:1111 1110
//补:1111 1111
printf("a=%d,b=%d,c=%d",a,b,c);
//在这以%d的形式输出,机会发生整形提升,在高位前补符号位,
//因为char 和 signed char 类型在编译器中默认是一样的,所以提升之后输出结果一致,
//但unsigned char默认是无符号类型,在内存中补码为1111 1111编译器默认最高位1不是符号位,
//而是数值位,且提升为整形所以会在最高位前补0,补完之后为整形类型最高位为0,所以输出为255.
return 0;
}
上述代码中,我们可以知道在内存中数据储存是补码,且操作数据也是对补码进行操作。
我们进一步可推:signed char取值范围:-128-127 unsigned char 0-255 其他类型也可以此推理
补位规则:
提升补高位,无符号数补0,有符号数补符合位。
不知道原码补码反码怎么转换可看:原码,反码,补码转换,以及其他数据类型的储存
在看这个代码:
#include <stdio.h>
int main()
{
char a = -128;
//首先-128为整形
//-128 原:1000 0000 0000 0000 0000 0000 1000 0000
//反:1111 1111 1111 1111 1111 1111 0111 1111
//补:1111 1111 1111 1111 1111 1111 1000 0000
//发生截断给到a
//1000 0000-a
//先将a提升到整形:1111 1111 1111 1111 1111 1111 1000 0000
//%u打印时认为这个数是无符号所以最高位不是符号位
//所以打印ff ff ff 80
//下图运行所得为十进制
printf("%u\n",a);
return 0;
}
%u 打印无符号整形,认为内存中补码对应的是无符号的数
2.截断
将字节多的数据类型赋给一个占字节少的变量类型 ,会发生“截断”。
看如下代码:
#include <stdio.h>
int main()
{
int i = 400;
//0000 0000 0000 0000 0000 0001 1001 0000
char a;
a = i;
//将后八位截断给到a。
//a-1001 0000
//然后a以%d输出整形提升a-11111 1111 1111 1111 1111 1111 1001 0000(补码)
//反码:1111 1111 1111 1111 1111 1111 1000 1111 (-1)
//原码:1000 0000 0000 0000 0000 0000 0111 0000(取反)- -112
printf("%d\n", a);
return 0;
}
如果帮到你的话,就请点个赞吧!