浅谈char类型的范围

在C语言中我们知道signed char类型的大小范围是-128~127.signedchar类型占了1个字节(=8位),我们知道有一种可以计算数据类型范围的公式是整型范围公式:-2^(n-1)~2^(n-1)- 1,那么signedchar类型的范围就是-2^7~2^7-1.
        同样的对于无符号unsigned char类型所表示的数值范围可用二进制表示换即为:0000 0000 ~ 1111
1111,转为十进制的话,那么unsignedchar类型的数值范围就是0~255,但是对于有符号的整数而言,二进制表示中的最高位表示的是正负(符号位),这样的话用二进制形式表示数值的大小时我们可用的位数会减少一位(最高位仅表示数值的正负,当最高位为0时该二进制数为正数,当二进制数为1时,该二进制数则表示为一个负数),也就是说在signedchar类型中的范围可以表示为1111 1111 ~ 01111111之间,即为-127~127.可是教材上说的范围却是-128~127之间,那到底是为什么呢?别急,首先让我来说说计算机内部整数的存储形式吧,当我们要算1 1的时候计算机会将它们转换成二进制来进行计算,即为00000001+0000 0001 = 0000 0010 (即为2),但是当我们要进行1-1的操作时计算机会将减法转换成加法运算,即为 1 (-1)

按照我们说的最高位为1时表示负数,那么有0000 0001+1000 0001 = 1000 0010(即为-2),但是1 - 1 != -2啊,所以呢计算机的大牛们发明了反码,直接用二进制的形式来表示的叫做原码,反码就是原码除了最高位以外的其他位全部取反,规定:正数的反码和原码相同,而负数的反码是原码除了符号位以外其余各位均取反的结果.所以呢,-1的原码为1000 0001,-1用反码表示为1111 1110那么1 (-1)可以表示为 0000 0001+1111 1110,再给结果取反转换为原码,即为0000 0001+1111 1110 = 1111 1111取反为1000 0000(即为-0).

现在我们终于解决了减法出现的问题,可是现在我们却发现了一个新的问题,1000 0000表示的是-0,这与0000 0000表示的0重复了,那么问题来了,既然0000 0000已经表示了0, 那么多出来的1000 0000就没有属于与0000 0000重复的多余的数据了,我们只需要一个0就够了,为了避免两个0的问题,于是计算机大牛们又发明了补码,补码的规定是这样的,正数的补码是其本身, 负数的补码为其反码加一,那么负数转化为补码需要两个步骤(1).先转化为反码.(2)再把反码加一其可得到补码.所以呢-1的补码即为1111 1111, 那么1 (-1) = 1 0000 0000,变成了9位,但是在char类型中仅有8位,于是计算机会把溢出的一位丢弃, 即结果是0000 0000,也就是说1 (-1) = 0000 0000(即为0),补码的操作会让0的二进制表示只有0000 0000, 比如说-0的原码为1000 0000 补码为1 0000 0000由于char类型只占8位,最高位被丢弃后结果为0000 0000, 0的原码为0000 0000,所以补码的发明弥补了0的重复,这样呢signed char类型的范围-127~0~127我们都可以用二进制表示了,仅剩下1000 0000没有用,1000 0000即表示为-128.

为什么要用1000 0000表示-128呢, 再来看, -128的原码为 1 1000 0000(最高位为符号位),其反码为1 0111 1111, 进而补码为 1 1000 0000,这是-128的补码,我们会发现它的原码和补码是相同的,其实呢这两个相同并非实质上的相同,但是char类型中是可以用1000 0000来表示-128的,关键在于char类型是8位,

它把-128的最高位符号位1丢弃了,-128的二进制中最高位被截断后的原码为1000 0000与-0的原码相同,

也就是说 1000 0000和-128丢弃最高位后余下的8位相同,所以让-0来表示-128.好了,今天就说到这里吧.


版权声明:本文为gc348342215原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。