学习目标:
计算机中用来表示带有符号整数的三种编码方式,大小端字节序。
学习内容:
原码是一种表示数字的编码方式,也称为符号位表示法。在原码中,一个数的最高位是符号位,0表示正数,1表示负数。其余位表示数值的绝对值,例如+7的原码为 00000111,-7的原码为 10000111。在原码表示下,0有两种表示方式,即 00000000 和 10000000。原码的优点是简单、易于实现,但缺点是存在符号位翻转问题,即加减法会产生错误的进位或借位问题。
注:一个数的原码是这个数直接转换成二进制。
反码是一种二进制数的表示方法,其中正数的反码与原码相同,负数的反码是符号位不变,其他位取反。例如,+7的反码为 00000111,-7的反码为 11111000。在反码中,0也有两种表示方式,即 00000000 和 11111111。 反码的优点是解决了原码加减法进位和借位的问题,但是也存在着正零与负零的问题。负零是指 -0 = 10000000,正零是指 +0 = 00000000。
注:反码是原码的二进制符号位不变,其他位按位取反。
补码也是一种二进制数的表示方法,其中正数的补码与原码相同,负数的补码是该数的反码加1。例如,+7的补码为 00000111,-7的补码为 11111001。在补码中,只有一种表示方式为0,即 00000000,不存在正零与负零的问题。
补码的优点是使用补码进行加减法运算时,可以统一运算方式,不需要考虑正负数的问题,同时也避免了原码加减法的进位和借位问题。补码在计算机中应用广泛,因为计算机中的加减法运算使用的就是补码。
注:补码是反码的二进制加1。
例题1:
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
例题2:
int main()
{
char a[1000]={0};
int i=0;
for(i=0;i<1000;i++)
{
a[i]=-1-i;
}
printf("%d",strlen(a));
return 0;
}
//运行结果:255
大小端是指在存储多字节数据时,字节的排列顺序不同。在大端字节序中,高位字节存储在低位地址,低位字节存储在高位地址,而在小端字节序中,高位字节存储在高位地址,低位字节存储在低位地址。
例如,对于十六进制数0x12345678,在大端字节序中,它的存储顺序为:0x12 0x34 0x56 0x78,而在小端字节序中,它的存储顺序为:0x78 0x56 0x34 0x12。
不同的处理器架构和操作系统有不同的字节序,例如Intel x86架构使用的是小端字节序,而Motorola 68000架构使用的是大端字节序。在网络通信中,通常使用大端字节序(也称为网络字节序)来保持数据的一致性。为此,常常需要进行字节序转换,将数据从主机字节序转换为网络字节序或从网络字节序转换为主机字节序。
例题:
unsigned int a=0x1234;
unsigned char b=*(unsigned char *)&a;
这段代码在32位大端模式处理器上变量b等于_____。
正确答案:0x00