在 16 位 C 编译器中,我们有 2 个字节用于存储整数,1 个字节用于存储字符。对于无符号整数,范围是 0 到 65535。对于有符号整数,范围是 -32768 到 32767。对于无符号字符,0 到 255。根据整数类型,有符号字符范围不应该是 -128 到 127。但是为什么-127到127?剩下的一点呢?
1 回答
我认为你混合了两件事:
- 标准要求的
signed char
范围等int
。 - 如今,大多数硬件都实现了哪些范围。
只要实现的范围是标准要求的范围的超集,这些不一定必须相同。
根据C 标准SCHAR_MIN
,和的实现定义值的SCHAR_MAX
大小(绝对值)应等于或大于,并且符号相同:
SCHAR_MIN -127
SCHAR_MAX +127
即只有 255 个值,而不是 256。
但是,由兼容实现定义的限制在数量上可能比这些“更大”。即[-128,+127]
标准也允许。而且由于大多数机器以2 的补码形式表示数字,[-128,+127]
因此您最常看到的范围是。
实际上,即使int
是 C 标准定义的最小范围也是关于零对称的。这是:
INT_MIN -32767
INT_MAX +32767
即只有 65535 值,而不是 65536。
但同样,大多数机器使用2 的补码表示,这意味着它们提供范围[-32768,+32767]
。
虽然在2 的补码形式中,可以用 8 位(即[-128,+127]
)表示 256 个有符号值,但还有其他有符号数表示是不可能的。
在符号幅度表示中,为符号保留一位,因此:
00000000
10000000
两者的意思相同,即0
(或者更确切地说,+0
和-0
)。
这意味着,一个价值被浪费了。因此,符号幅度表示只能以 8 位保存从 -127 ( 11111111
) 到 +127 ( ) 的值。01111111
在一个的补码表示中(通过按位 NOT 求反):
00000000
11111111
两者的意思相同,即0
。
同样,只有从 -127 ( 10000000
) 到 +127 ( 01111111
) 的值可以用 8 位表示。
如果 C 标准要求范围为[-128,+127]
,那么这将基本上排除使用这种表示的机器能够有效地运行 C 程序。他们需要一个额外的位来表示这个范围,因此需要 9 位而不是 8 位来存储有符号字符。基于上述的逻辑结论是:这就是 C 标准要求[-127,+127]
有符号字符的原因。即允许实现自由选择适合其需求的整数表示形式,同时能够以有效的方式遵守标准。同样的逻辑也适用int
。