【问题标题】:Why does subtracting '0' in C result in the number that the char is representing?为什么在 C 中减去 '0' 会导致 char 所代表的数字?
【发布时间】:2013-03-13 23:36:08
【问题描述】:

有人能解释一下为什么会这样吗?

char c = '9';
int x = (int)(c - '0');

为什么从 char 的 ascii 代码中减去“0”会得到该 char 所代表的数字?

【问题讨论】:

  • 这是个好问题。不过,不要被所有使用 ASCII 表作为观察到的行为解释的答案分心。

标签: c++ c digits


【解决方案1】:

因为 char 都用数字表示,而 '0' 是第一个。

在下表中您可以看到:

'0' => 48
'1' => 49


'9' => 57.

结果: ('9' - '0') = (57 − 48) = 9

来源:http://www.asciitable.com

【讨论】:

  • the machine I work on 我们有'0' => 240,但'9' - '0' 仍然是9。
  • +1。 (EBCDIC 有点奇怪),但你是对的。这就是为什么'9' - '0' 是正确的做法,应该避免'9' - 48。 On 总是可以期望字符 0 到 9 按升序设置,但它们的实际值可能不同。
  • 这假定正在使用 ASCII 编码。
  • @LightnessRacesinOrbit - 不,它没有。它假定使用的任何编码都具有连续存储的值 0 到 9 的内部表示(并且按升序)。它们的绝对值无关紧要,它们的顺序性才是最重要的。祝你好运找到不按顺序存储它们的相关字符集。
  • @AaronHS:您对数字是正确的(如您所说,这些数字需要按升序连续存储)。我假设我指的是 ASCII 表的突出用途来证明这一点 - 关于数字表示要求的标准引用会更合适。
【解决方案2】:

char 是一个整数类型,就像int 和家庭一样。 char 类型的对象有一些数值。您在字符文字中键入的字符(如'0')与char 对象具有的值之间的映射由执行字符集中该字符的编码决定: p>

  • C++11 §2.14.3:

    包含单个 c-char 可在执行字符集中表示的普通字符文字的类型为 char,其值等于 c- 编码的数值char 在执行字符集中。

  • C99 §6.4.4.4:

    整数字符常量是一个或多个用单引号括起来的多字节字符的序列,如'x'

    [...]

    整数字符常量的类型为int

    请注意,int 可以转换为 char

执行字符集的选择取决于实现。通常情况下,选择与 ASCII 兼容,因此其他答案中发布的表格具有适当的值。然而,字符集并不需要兼容 ASCII。不过有一些限制。其中之一如下(C++11 §2.3,C99 §5.2.1):

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " ’

[...]

在源基本字符集和执行基本字符集中,上述十进制数字列表中0之后的每个字符的值都应比前一个字符的值大1。

这意味着无论字符'0' 具有什么值,字符'1' 的值都比'0' 大一,而字符'2' 的值多一,以此类推。数字字符具有连续值。您可以像这样总结映射:

Character:            0    1    2    3    4    5    6    7    8    9
Corresponding value:  X    X+1  X+2  X+3  X+4  X+5  X+6  X+7  X+8  X+9

所有数字字符的值都偏离'0' 的值。

这意味着,如果你有一个字符,比如说'9' 并从中减去'0',你会得到执行字符集中'9' 的值和'0' 的值之间的“距离” .由于它们是连续的,因此距离将为 9。

【讨论】:

  • 在 C 中,一个普通的字符文字 ... 的类型为 int
  • @pmg 我没有注意到这个问题也被标记为c。我将添加差异。
  • 明确一点,保证'a' .. 'z' 是连续的,实际上它们不在EBCDIC 中。 (它们是 ASCII / Unicode)。您引用了一个以字母开头的列表,但关键短语是“0 之后的每个字符”,并且该列表将字母放在首位。
【解决方案3】:

因为 C 标准保证字符 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 始终按照其数字字符代码的顺序排列。所以,如果你从另一个数字中减去'0' 的字符代码,它将给出它相对于0 的位置,也就是它的值...

来自 C 标准,第 5.2.1 节字符集:

在源和执行基本字符集中, 上述十进制数字列表中 0 之后的每个字符的值应大于 1 前一个的值

【讨论】:

  • +1,但最好添加指定的标准部分的编号。
【解决方案4】:

因为,字面量是按顺序排列的。

因此,如果0 是 48,1 将是 49,2 将是 50 等等。在 ASCII 中,那么 x 将包含 '9' 的 ascii 值减去 @987654326 的 ascii 值@ 这意味着,'9' 的 ascii 值为 57,因此,x 将包含 57 - 48 = 9

另外,char 是一个整数类型。

【讨论】:

  • 是的,你是对的,现在说得通了,谢谢! (这不是一个非常聪明的问题;D)
  • 这不取决于语言环境是 ASCII。
【解决方案5】:

数字字符的代码 ascii 按'0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 的顺序排列,如ascii table 所示

所以如果我们在 '9' 的 asii 和 '0' 的 ascii 之间有所不同,我们将得到 9

【讨论】:

    【解决方案6】:

    在 ASCII 表中,数字按顺序排列,从 0 的最低代码开始。如果从0 中减去一个更大的数字,就会产生两个 ASCII 值的差值。 所以,9 的值是 570 的值是 48,所以如果你从 57 中减去 48,你会得到 9。 只需看看 ASCII 表。

    here

    【讨论】:

      【解决方案7】:

      ASCII TABLE

      '9' in ASCII =  57 //in Decimal
      
      '0' in ASCII =  48 //in Decimal
      

      57 - 48 = 9

      【讨论】:

      • 我相信它会是一样的,因为 '0'-'9' 是按递增顺序排列的。因为即使它在this。 '0' - '9' 也按升序排列。
      • 对,就是这个问题。某处有一条规则说数字必须按递增顺序排列,而 ASCII 表遵循此规则。因此,可以保证此行为适用于其他编码。但是仅仅引用 ASCII 表是没有解释的。
      • 感谢您的建议。我会确保下次我会解释。 ;)
      【解决方案8】:

      首先,尝试:

      cout << (int)'0' << endl;
      

      现在试试:

      cout << (int)'9' << endl;
      

      字符以文本形式表示数字,但在作为数字时具有不同的值。 Windows 使用数字来决定打印哪个字符。所以数字 0x30 代表 windows 操作系统中的字符 0。数字 0x39 代表字符 9。毕竟计算机能识别的都是数字,它不知道什么是“字符”。

      很遗憾,(int)('f' - '0') 不等于 15。

      这为您提供了各种字符和窗口用来表示它们的数字。 http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

      如果您需要为其他操作系统找到它,您可以在 Google 中搜索:Virtual Key Codes &lt;OSname&gt;。查看其他操作系统的代码。

      【讨论】:

      • 这与 Windows(或任何其他操作系统,例如创建 C 的操作系统)无关。数字字符的连续编码是 C 标准所要求的,并且可以依赖于任何符合标准的系统。
      猜你喜欢
      • 2021-02-01
      • 1970-01-01
      • 2013-10-04
      • 2022-06-11
      • 2020-08-12
      • 2013-08-22
      • 1970-01-01
      • 2014-08-08
      • 2012-01-08
      相关资源
      最近更新 更多