我们都知道C语言中整形是以补码的形式存在的,正整数的源 反 补码,三码相同,但是负数的存储就不一样了,需要由源码得到反码来存储,现在我们来做一道题。
#include <stdio.h>
int main()
{
char a=-1;
signed char b=-1;
unsigned char c=-1;
printf("%d %d %d",a,b,c);
}
这里的答案是a=-1 b=-1 c=255,好像和我们想象的不一样,我们一点点来分析,a为char类型,-1的反码在内存里面是32位,全部为1,但是a为char类型的,所以只取后8位,全部是1,因为pirntf 后面是%d所以,要进行类型提升,取符号位1进行补充前面空缺的24位,那么还是32个1,答案自然就是-1,b也是如此,但是C是无符号类型的所以c为恒正数补冲的时候就是填充的0,那么前面的就都是0,剩下8位1,计算得就是255。
我们再来一道题练习一下
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;
}
这里的答案是300 44,printf在传入参数的时候如果是整形会默认传入四字节,所以a+b的结果是用一个四字节的整数接收的,不会越界。而c已经在c = a + b这一步中丢弃了最高位的1,所以只能是300-256得到的44了。
※由于printf是可变参数的函数,所以后面参数的类型是未知的,所以甭管你传入的是什么类型,printf只会根据类型的不同将用两种不同的长度存储。其中8字节的只有long long、float和double(注意float会处理成double再传入),其他类型都是4字节。所以虽然a + b的类型是char,实际接收时还是用一个四字节整数接收的。另外,读取时,%lld、%llx等整型方式和%f、%lf等浮点型方式读8字节,其他读4字节。