这是我的代码
#include<stdio.h>
void main()
{
char ch = 129;
printf("%d", ch);
}
我得到的输出为 -127。这是什么意思?
最佳答案
表示 char
是一个 8 位变量,只能容纳 2^8 = 256 个值,因为声明是 char ch
, ch
是一个 signed
变量,也就是说它可以存储 127 个正负值。当您要求超过 127 时,该值将从 -128 重新开始。
把它想象成一些街机游戏,你从屏幕的一侧到另一侧:
ch = 50;
-----> 50 is stored
|___________________________________|___________| since it fits
-128 0 50 127 between -127
and 128
ch = 129;
--- 129 goes over
--> 127 by 2, so
|__|____________________________________________| it 'lands' in
-128 -127 0 127 -127
但!!你不应该依赖这个,因为它是未定义的行为!
为了纪念 Luchian Grigore,这里是正在发生的事情的位表示:
char
是一个保存 8 位或一个字节的变量。因此,我们有 8 个 0 和 1 正在努力表示您想要的任何值。如果 char
是一个 signed
变量,它将表示它是正数还是负数。您可能读过代表符号的一位,这是对真实过程的抽象;事实上,它只是最早在电子产品中实现的解决方案之一。但是这样一个微不足道的方法有一个问题,您将有两种表示 0 的方式(+0 和 -0):0 0000000 -> +0 1 0000000 -> -0
^ ^
|_ sign bit 0: positive |_ sign bit 1: negative
保证不一致!!因此,一些非常聪明的人想出了一个名为 Ones' Complement 的系统,它将一个负数表示为它的正对应物的否定(非操作):
01010101 -> +85
10101010 -> -85
这个系统……有同样的问题。 0 可以表示为
00000000
(+0) 和 11111111
(-0)。然后来了一些更聪明的人,他们创建了两个补码,它将保留先前方法的否定部分,然后加 1,因此删除了那个讨厌的 -0 并为我们的范围提供了一个 Shiny 的新数字:-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
,从而破坏了它通过一维欧几里得空间中的实数轴发生臭味偏移的所有正潜力。关于c - C 中的简单字符解释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9125408/