9

在 16 位 C 编译器中,我们有 2 个字节用于存储整数,1 个字节用于存储字符。对于无符号整数,范围是 0 到 65535。对于有符号整数,范围是 -32768 到 32767。对于无符号字符,0 到 255。根据整数类型,有符号字符范围不应该是 -128 到 127。但是为什么-127到127?剩下的一点呢?

4

1 回答 1

21

我认为你混合了两件事:

  1. 标准要求的signed char范围等int
  2. 如今,大多数硬件都实现了哪些范围。

只要实现的范围是标准要求的范围的超集,这些不一定必须相同。

根据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

于 2012-07-27T08:55:17.203 回答