1.符号位
首先在VS(2022)中,最高位是符号位 0为正,1为负
2.负数存取形式
负数在内存中存储的时候,存储的是二进制的补码(原码取反加一)
而打印时,打印的是这个数的原码(符号位不变,补码减一取反)
什么意思呢?
以int a=-1 为例:
int 为整型,大小为4字节,一个字节是八个比特位,而一个比特位可以表示两个数(0和1)
,所以int a =-1 首先写成二进制的形式为:10000000 00000000 00000000 00000001(原码)
取反变成(取反时符号位不变):11111111 11111111 11111111 11111110
+1变成 11111111 11111111 11111111 11111111;
#include <stdio.h>
int main()
{
int a =-1;
}
你看,我们在内存中的储存就是ff ff ff ff
ff是16进制数15的意思(a是10,b是11...到f15),1个16进制数用4个比特位表示
所以第一个 f 表示一个字节8个比特位中的前4个是四个一 1111后一个f表示剩下的4个比特位也是八个一,所以ff的意思就是11111111,而int是整型4个字节,所以有4组ff;
打印时打印的是原码
原码等于补码减一取反
补码:11111111 11111111 11111111 11111111
减一:11111111 11111111 11111111 11111110
取反:10000000 00000000 00000000 00000001(符号位不变)
所以打印出来的就是-1了;
那为什么说unsigned int a=-1,打印出来的是一个超大的整数呢?
你肯定想到了:就是unsigned int(无符号整型) 最高位不代表符号位了,而是代表2^31+1这个数
所以变的超大嘛
有了int这个基础那么char类型的就不在话下了
char为字符数据类型,大小为1个字节,1个字节为8个比特位,而一个比特位可以代表两个数
(0和1)所以一个char类型数,可以表示 2^8-1==255个数,但不是0-255,为什么呢?
因为最高位1是符号位嘛
正数从 00000000 ->00000001一直到01111111 就是0-127
负数从 10000000->10000001一直到11111111就是(-128)到 (-1) 参考上文负数的打印规则
接下来你可以试试以下代码体验一下了
#include <stdio.h>
int main()
{
unsigned char a = -1;
char a1 = 128;
printf("%d\n", a);
printf("%d\n", a1);
return 0;
}