目录
原码、反码、补码
整型在内存中是以补码的形式存放的
正数 | 负数 | |
---|---|---|
原码 | 整数的二进制形式,包括符号位和数值位,符号位是最高位,正数用‘0’表示 | 整数的二进制形式,包括符号位和数值位,符号位是最高位,负数用‘1’表示 |
反码 | 同原码 | 将原码的符号为不变,其他位依次按位取反 |
补码 | 同原码 | 反码+1 |
大小端存储
大端字节存储:数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中;
小端字节存储:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中;
练习及解析
1、下面代码输出什么
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
用代码注释解析如下:
#include <stdio.h>
int main()
{
char a= -1;
//(-1的原码)10000000000000000000000000000001
//(-1的反码)11111111111111111111111111111110
//(-1的补码)11111111111111111111111111111111
//把-1的补码放到char类型的a中,会发生截断,取低八位二进制位,即11111111
signed char b=-1;
//-1的原码、反码、补码不变
//把-1的补码放到signed char类型的b中,会发生截断,取低八位二进制位,即11111111
unsigned char c=-1;
//-1的原码、反码、补码不变
//把-1的补码放到signed char类型的b中,会发生截断,取低八位二进制位,即11111111
printf("a=%d,b=%d,c=%d",a,b,c);
//a:最后要以整型的形式打印,a会发生整型提升,因为a是char类型的,会以最高位的数值向前补位,即1
// 提升后结果:11111111111111111111111111111111(内存中的补码形式)
// 因为最终打印的结果是原码的十进制表示,所以补码转为原码(除符号位以外取反、+1):10000000000000000000000000000001(-1)
//b:同a
//c:最后要以整型的形式打印,c会发生整型提升,因为c是unsigned char类型的,属于无符号类型,所以前面会补24位0
// 提升后结果:00000000000000000000000011111111(内存中的补码形式)
// 因为最终打印的结果是原码的十进制表示,补码的最高位是0,所以原码和补码相同,也就是打印出来的结果,转为十进制就是255
return 0;
}
输出结果:-1 -1 255
2、下面代码输出什么
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
用代码注释解析如下:
#include <stdio.h>
int main()
{
char a = -128;
//(-128的原码)10000000000000000000000010000000
//(-128的反码)11111111111111111111111101111111
//(-128的补码)11111111111111111111111110000000
//把-128的补码放到char类型的a中,会发生截断,取低八位二进制位,即10000000
printf("%u\n",a);
//结果用无符号整型打印,a会发生整型提升,因为a是char类型的,会以最高位的数值向前补位,即1
//提升后结果:11111111111111111111111110000000(内存中的补码形式)
//因为是无符号整型,所以原码和补码相同,转为十进制:4294967168
return 0;
}
输出结果:4294967168
3、下面代码输出什么
#include <stdio.h>
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;
}
用代码注释解析如下:
#include <stdio.h>
int main()
{
unsigned char a = 200;
//(200的原、反、补码)00000000000000000000000011001000
//(放到无符号字符型a中发生截断)
//a:11001000
unsigned char b = 100;
//(100的原、反、补码)00000000000000000000000001100100
//(放到无符号字符型b中发生截断)
//b:01100100
unsigned char c = 0;
c = a + b;
//先整型提升再运算
//因为a和b都是无符号字符型,所以前面补24位0到整型32位
//a:00000000000000000000000011001000
//b:00000000000000000000000001100100
//a+b:00000000000000000000000100101100
//a+b放到无符号字符型c中发生截断
//c:00101100
printf("%d %d", a+b,c);
//直接打印a+b(不发生截断):300
//无符号字符型c以整型形式打印,前面补24位0:44
return 0;
}
输出结果:300 44