16位数据类型范围内的混淆

Smi*_*yne 7 c int primitive range char

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

Arj*_*kar 18

我认为你混合了两件事:

  1. 什么范围的标准需要signed char,int等等.
  2. 目前,大多数硬件都实现了哪些范围.

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

根据C标准,执行定义的值SCHAR_MINSCHAR_MAX 应在幅度(绝对值)等于或大于到,并且相同的符号的:

SCHAR_MIN  -127
SCHAR_MAX  +127
Run Code Online (Sandbox Code Playgroud)

只有255个值,而不是256个.

但是,由兼容实现定义的限制可能比这些限制"更大".也就是[-128,+127]标准也允许.而且,由于大多数机器代表了数字2的补码形式,[-128,+127]是你将能看到最常用的范围内.

实际上,即使int C标准定义的最小范围也是零对称的.它是:

INT_MIN    -32767
INT_MAX    +32767
Run Code Online (Sandbox Code Playgroud)

只有65535个值,而不是65536个.

但同样,大多数机器使用2的补码表示,这意味着它们提供了范围[-32768,+32767].

虽然在2的补码形式中,可以用8位(即[-128,+127])表示256个有符号值,但还有其他有符号数表示,这是不可能的.

符号幅度表示中,为符号保留一位,因此:

00000000
10000000
Run Code Online (Sandbox Code Playgroud)

两者意味着相同的事情,即0(或更确切地说,+0-0).

这意味着浪费了一个价值.因此,符号幅度表示只能在8位中保存-127(11111111)到+127(01111111)的值.

一个补码表示中(通过按位NOT来否定):

00000000
11111111
Run Code Online (Sandbox Code Playgroud)

两者意味着相同的事情,即0.

同样,只有-127(10000000)到+127(01111111)的值才能用8位表示.

如果C标准要求范围[-128,+127],那么这将基本上排除使用这种表示的机器能够有效地运行C程序.它们需要一个额外的位来表示这个范围,因此需要9位来存储有符号的字符而不是8个.基于上述的逻辑结论是:这就是C标准需要[-127,+127]有符号字符的原因.即允许实现自由选择适合其需要的整数表示形式,同时能够以有效的方式遵守标准.同样的逻辑也适用int.