这是我的代码
#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 的系统,它将负数表示为正数的否定(NOT 运算):
01010101 -> +85
10101010 -> -85
这个系统...有同样的问题。 0 可以表示为 00000000
(+0) 和 11111111
(-0)。然后出现了一些更聪明的人,他们创建了 Two's Complement,它将保持早期方法的否定部分,然后加 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 导致变量必须被 signed
破坏了它在一维欧几里德空间中通过实数线进行臭味转移的所有积极潜力。
关于c - C语言中的简单字符解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9125408/