提到这个问题,我们先来做一个-128的原码补码转换(前提假设看到这篇博客的看官会原码补码)
-128
原码 1000 0000
反码 1111 1111
补码 1 1000 0000(这里为什么会多出来一个1)
在进行原码反码转换的时候,反码从左往右第二个1,加1变成10,如补码所示,补码最高位的1是一个符号位,那么这个多出来的符号位1是不是和大家接触的数据类型内存块大小不一致,为什么signed char最小不用-127(1111 1111)表示,而用-128(1000 0000)表示。
这里就要注意,关键在于signed char或者说char数据类型不论有无符号,在C/C++语言中占用的内存的空间均为1B,也就是8bit,是可以用1000 0000表示-128的,它是把最高位符号位丢弃了,截断后的-128的补码和原码一致,这里不知道大家有没有发现-0和这个-128的原码看起来的有点眼熟的意思。 没错,-0(1000 0000)和-128(1000 0000)原码相同,也就说1000 0000和-128丢弃最高位后余下的8位相同,所以-0也可以也可以用来表示-128. 这样子,截断后的-128和char型范围其他数 (-127~127)运算也不会影响结果,所以才敢这么表示-128.
比如 -128+(-1)
1000 0000 ------------------丢弃最高位的-128
+ 1111 1111 ----------------- -1
________________
10111 1111 ------------------char 取八位,这样结果不正确,不过没关系 ,结果-129本来就超出char型了,当然不能表示了。
再比如 -128+127
1000 0000
+ 0111 1111
————————
1111 1111 -------------- -1 结果正确, 所以,这就是为什么能用 1000 0000表示-128的原因。
这样就是为什么signed char是-128~127,而不是-127~127。short int同样也是如此,对与short int的范围:-32768~32767,因为在16位中,-32768位的原码是17位(16+1),丢弃最高位‘1’,剩下的位与-0的原码相同,说到这里,还真是佩服设计计算机的前辈!!!!