c - C语言中的简单字符解释

标签 c format char

这是我的代码

 #include<stdio.h>

 void main()
 {
     char ch = 129;
     printf("%d", ch);
 }

我得到的输出为 -127。什么意思?

最佳答案

这意味着 char 是一个 8 位变量,只能保存 2^8 = 256 个值,因为声明是 char chch 是一个 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/

相关文章:

c - 当用户按 "Enter"而不是一个空格字符时如何结束该程序?

java - 如何将 Android 的 WifiService 操作调试到驱动程序级别?

c - C 程序中的 stdout 转义查询和 stdin 冲突(无 ncurses)

zip - 如何在Zip文件中找到中央目录的位置?

php - 将时间字符串转换为小数小时 PHP

C - fgets() - 换行符的长度

c# - 在 C# 中将字符串中的多个字符替换为多个值

c - 6502 仿真器上的 EhBASIC 输入

Java:搜索两个字符串之间的第一个公共(public)字符

Python 输出带有按值着色的 float 的复杂行