代表着char
是一个 8 位变量,只能保存 2^8 = 256 个值,因为声明是char ch
, ch
is a signed
变量,这意味着它可以存储 127 个负值和正值。当您要求超过 127 时,该值将从 -128 开始。
可以将其想象为一些街机游戏,您可以从屏幕的一侧移动到另一侧:
ch = 50;
-----> 50 is stored
|___________________________________|___________| since it fits
-128 0 50 127 between -127
and 128
通道=129;
--- 129 goes over
--> 127 by 2, so
|__|____________________________________________| it 'lands' in
-128 -127 0 127 -127
但!!你不应该依赖它,因为它是未定义的行为!
为了纪念 Luchian Grigore,以下是所发生事件的位表示:
A char
是一个保存 8 位或一个字节的变量。所以我们有 8 个 0 和 1 来努力代表你想要的任何值。如果char
is a signed
变量它将表示它是正数还是负数。您可能读过代表符号的一位,这是真实过程的抽象;事实上,它只是电子领域最早实施的解决方案之一。但这样一个简单的方法有一个问题,你有两种表示 0 的方法(+0 和 -0):
0 0000000 -> +0 1 0000000 -> -0
^ ^
|_ sign bit 0: positive |_ sign bit 1: negative
保证不一致!因此,一些非常聪明的人想出了一个称为“补码”的系统,它将负数表示为其正数的负数(非运算):
01010101 -> +85
10101010 -> -85
这个系统……也有同样的问题。 0 可以表示为00000000
(+0) 和11111111
(-0)。然后一些更聪明的人创建了补码,它将保留早期方法的负部分,然后加 1,从而删除那个讨厌的 -0 并为我们的范围提供一个闪亮的新数字:-128!那么我们的范围现在怎么样?
00000000 +0
00000001 +1
00000010 +2
...
01111110 +126
01111111 +127
10000000 -128
10000001 -127
10000010 -126
...
11111110 -2
11111111 -1
因此,这应该可以让我们了解当我们的小处理器尝试向变量添加数字时会发生什么:
0110010 50 01111111 127
+0000010 + 2 +00000010 + 2
------- -- -------- ---
0110100 52 10000001 -127
^ ^ ^
|_ 1 + 1 = 10 129 in bin _| |_ wait, what?!
是的,如果您查看上面的范围表,您可以看到最多 127 (01111111
)二进制文件很好,没有什么奇怪的事情发生,但是在第 8 位设置为 -128 之后(10000000
) 解释的数字不再保留其二进制大小,而是保留二进制补码表示形式。这意味着,二进制表示,变量中的位,1 和 0,我们心爱的人的心脏char
,确实有 129...它在那里,看看它!但邪恶的处理器读取到 -127 会导致变量 HAD 变为signed
破坏了它在一维欧几里得空间中的实数轴上发生臭味转移的所有积极潜力。