【问题标题】:Adding and subtracting chars, why does this work? [duplicate]添加和减去字符,为什么会这样? [复制]
【发布时间】:2014-01-18 18:42:55
【问题描述】:

我正在通过 Daniel Liang 在第 9 章“字符串”的“Java 编程入门第 9 版”学习 Java,我遇到了这段代码:

public static int hexCharToDecimal(char ch) {
   if (ch >= 'A' && ch <= 'F')
       return 10 + ch - 'A';
   else
      return ch - '0';
}

有人能解释一下这里发生了什么吗?如何从整数中添加/减去字符以及它背后的含义是什么?

【问题讨论】:

标签: java


【解决方案1】:

来自Docs

char 数据类型是单个 16 位 Unicode 字符。

char 由其代码点值表示:

  • 分钟'\u0000'(或0)
  • 最大值:'\uffff'(或 65,535)

您可以在ASCII table 上看到所有英文字母代码点。

请注意0 == \u000065,535 == \uffff,以及介于两者之间的所有内容。它们是对应的值。

char 实际上只是存储为一个数字(其代码点值)。我们有语法来表示像char c = 'A'; 这样的字符,但它等价于char c = 65; 并且'A' == 65 是真的。

因此,在您的代码中,字符由它们的十进制值表示以进行算术运算(从 0 到 65,535 的整数)。

例如,字符 'A' 由其代码点 65(ASCII 表中的十进制值)表示:

System.out.print('A'); // prints A
System.out.print((int)('A')); // prints 65 because you casted it to an int

注意,short 是一个 16 位 有符号 整数,所以即使 char 也是 16 位,@987654337 的最大整数值@ (65,535) 超过了 short (32,767) 的最大整数值。因此,从char 转换为(short) 并不总是有效。并且char 的最小整数值为0,而short 的最小整数值为-32,768。


对于您的代码,假设char'D'。注意'D' == 68,因为它的代码点是68

return 10 + ch - 'A';

这会返回10 + 68 - 65,所以它会返回13

现在假设字符是'Q' == 81

if (ch >= 'A' && ch <= 'F')

这是错误的,因为'Q' &gt; 'F' (81 &gt; 70),所以它会进入else 块并执行:

return ch - '0';

这会返回81 - 48,所以它会返回33

您的函数返回 int 类型,但如果它改为返回 char 或之后将 int 强制转换为 char,则返回的值 33 将代表 '!'字符,因为33 是它的代码点值。在 ASCII 表或 Unicode 表中查找字符以验证 '!' == 33(比较十进制值)。

【讨论】:

  • 感谢您的澄清
【解决方案2】:

这是因为 char 是可以用作数值的原始类型。字符串中的每个字符都被编码为一个特定的数字(并非在所有情况下都完全正确,但足以基本了解该问题),Java 允许您以这种方式使用字符。

它可能允许这样做主要是出于历史原因,这就是它在 C 中的工作方式,他们可能以“性能”或类似的东西来激励它。

如果你觉得这很奇怪,别担心,我也这么认为

另一个答案实际上是不正确的。 ASCII 是一种特定的编码(编码是一些说明“1 = A, 2 = B, ... , 255 = Space”的规范),这不是 Java 中使用的编码。 Java char 有两个字节宽,并通过 unicode 字符编码进行解释。

【讨论】:

    【解决方案3】:

    字符依次存储为整数(ASCII 值),以便您可以对整数执行 add 和 sub,这将返回 char 的 ASCII 值

    【讨论】:

    • 您能否根据我给出的示例详细说明一下,因为坦率地说,我仍然不明白其背后的逻辑
    • 10+'B'-'A' = 11 因为 B ASCII 值为 66,A ASCII 值为 65
    【解决方案4】:

    不管Java 实际如何存储char 数据类型,可以肯定的是,从字符'A' 中减去字符'A' 将表示为null 字符\0。在内存中,这意味着每一位都是0char 在内存中占用的内存大小可能因语言而异,但据我所知,null 字符在所有语言中都是相同的,每一位都等于0

    作为int的值,每一位等于0的一块内存代表0的整数值。

    事实证明,当您进行“字符数学”时,从任何其他字母字符(相同大小写)中减去任何字母字符会导致位被翻转,如果您将它们解释为int,表示这些字符之间的距离。此外,从任何其他数字 char 中减去 char '0' 将导致您从中减去的 char 的 int 值,原因基本相同。

    'A' - 'A' = '\0'
    'a' - 'a' = '\0'
    '0' - '0' = '\0'
    

    【讨论】:

      猜你喜欢
      • 2019-05-20
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      相关资源
      最近更新 更多