如何从char中减去字符’0’将其更改为int?

此方法适用于C,C ++和Java。 我想知道它背后的科学。

char的值可以是0-255,其中不同的字符映射到这些值之一。 数字也以'0''9'顺序存储,但它们通常也不存储为前十个char值。 也就是说,字符'0'的ASCII值不为0 。 char值0几乎总是\0 null字符。

在不知道关于ASCII的任何其他内容的情况下,如何从任何其他数字字符中减去'0'字符将导致原始字符的char值非常简单。

所以,这是简单的数学:

 '0' - '0' = 0 // Char value of character 0 minus char value of character 0 // In ASCII, that is equivalent to this: 48 - 48 = 0 // '0' has a value of 48 on ASCII chart 

所以,类似地,我可以使用任何char数字进行整数运算…

 (('3' - '0') + ('5' - '0') - ('2' - '0')) + '0') = '6' 

ASCII图表上520之间的差异恰好等于我们在看到该数字时通常会想到的面值。 从每个中减去char '0' ,将它们加在一起,然后在末尾添加'0'将为我们提供char值,该char值表示执行该简单数学运算的结果。

上面的代码片段模拟3 + 5 - 2 ,但在ASCII中,它实际上是这样做的:

 ((51 - 48) + (53 - 48) - (50 - 48)) + 48) = 54 

因为在ASCII图表上:

 0 = 48 2 = 50 3 = 51 5 = 53 6 = 54 

在C中, +-运算符将整数提升* 1应用于它们的参数,因此减去(或添加)两个char的结果是int * 2

从C标准:

5.1.2.3程序执行

[…]

10示例2执行片段

 char c1, c2; /* ... */ c1 = c1 + c2; 

”整数促销”要求抽象机器将每个变量的值提升为int size然后添加两个int s […]

将此应用于OP隐含给定的用例

 char c = 42; ... = c - `0`; 

这将导致上述内容与:

 ... = (int) c - (int) `0`; /* The second cast is redundant, as per Jens' comment. */ ^ ^ +------ int -----+ 

* 1:如果运算符参数的排名低于int则将它们提升为int
* 2: char的排名低于int

没有变化'0' 是C中的int 。 编写48 (假设ASCII)是一种奇特的方式。

你可以通过计算'0'的大小来说服自己这个事实:

  printf ("sizeof '0' is %zu\n", sizeof '0'); printf ("sizeof(char) is %zu\n", sizeof(char)); 

在第一行中很可能会打印4(或2),但可能不会像在第二行中那样打印(再次:在C中;它与C ++不同)。

数字常量0没有任何限定条件,类型为int 。 由于通常的类型提升过程,对charint的二进制减法运算的结果也具有int类型。