应用原码,反码和补码的几个小题

一、

//输出什么?
#include 
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;
} 

应用原码,反码和补码的几个小题_第1张图片分析:%d是打印一个有符号的十进制的整数(int)
char是一个字节的变量,当按照%d打印的时候,就会把char隐式转换成int类型的变量,再打印。
**

a

-1的补码
因为
0000 0001 1的原码
首位是符号位,改成1即-1的原码,所以
1000 0001 -1的原码
符号位不变,其余位取反即-1的反码
1111 1110 -1的反码
+1成补码
1111 1111 -1的补码(即-1在内存中的存储形式)
转换
%d打印的时候就把a先隐式转成int
转换过程中,高位的三个字节也需要填充,按照符号位填充(如果a的符号位是0,高位就补0,如果a的符号位是1,高位就补1)
char => int
1111 1111 => 1111 1111 1111 1111 1111 1111 1111 1111
-1的补码
高位补1,也就是为了防止出现这样转换过程中出现数据错误的情况
最后输出-1

b

signed char 等价于 char

c

1111 1111 -1在内存中的存储 =>unsigned char存的还是8个1,只不过此时的最高位的1不再是符号位了,8个1理解成正数(不考虑符号位)结果就是255
转换
%d打印时,高位补0,因为unsigned char 没有符号位

1111 1111 => 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111
最后输出255

二、

#include
int main()
{
 char a = -128;
 printf("%u\n", a);
 return 0;
}

应用原码,反码和补码的几个小题_第2张图片
1、看char型的-128在内存中的存储形式
128的原码 0000 0000 0000 0000 0000 0000 1000 0000
所以
-128的原码 1000 0000 0000 0000 0000 0000 1000 0000
取反
-128的反码 1111 1111 1111 1111 1111 1111 0111 1111
+1
-128的补码 1111 1111 1111 1111 1111 1111 1000 0000
char类型只有一个字节,所以截断,即
char a=-128 1000 0000
2、因为
%d:打印一个有符号十进制整数 , %u:打印一个无符号十进制整数
所以
需要进行隐式转换char => int => unsigned int
char=>int
转换过程中,高位的三个字节需要填充,按照符号位填充(如果a的符号位是0,高位就补0,如果a的符号位是1,高位就补1)
1111 1111 1111 1111 1111 1111 1000 0000 (int)
int => unsigned int
1111 1111 1111 1111 1111 1111 1000 0000 (unsigned int)
此时最高位不再是符号位,不再表示负数,为一个很大的数字
三、

#include 
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
} 

应用原码,反码和补码的几个小题_第3张图片
此时a为128
1、看char型的128在内存中的存储形式
128的原码 0000 0000 0000 0000 0000 0000 1000 0000
因为正数原码反码,补码相同,所以
128的反码 0000 0000 0000 0000 0000 0000 1000 0000
128的补码 0000 0000 0000 0000 0000 0000 1000 0000
类型只有一个字节,所以截断,即
char a=128 1000 0000
之后就跟char=-128一样了,最后输出了相同的数字

你可能感兴趣的:(c++,补码,内存结构)