使用 'a' - 'A' 而不是“32”或 space 字符背后的逻辑是什么?

What's the logic behind using 'a' - 'A' instead of "32" or the space character?

这是“The C Programming Language”一书中的一段代码,它将单个字符映射为 ASCII 字符集的小写字母并且 returns 不变,如果该字符不是大写字母:

int lower(int c)
{
    if (c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
    else
        return c;
}

我不明白return c + 'a' - 'A';背后的逻辑。

为什么他们不简单地用 ' ' 或数字 32 而不是 'a' - 'A'

在ASCII字符集中'a' - 'A'恰好有一个值32。它与ASCII space字符' '也有一个值32完全无关,所以它将 'a' - 'A' 替换为 ' '.

毫无意义

使用 'a' - 'A'32 更有意义和更容易理解,并且也不会将实现与使用特定字符集联系起来(尽管 a-zA-Z 需要连续才能工作,但并非所有字符集都如此)。

为什么不是 32?因为“幻数”不好。

通过使用 'a'-'A' 可以让 reader 清楚地知道当前字符编码中添加了大写和小写之间的字符编码差异。

请注意,这还取决于连续的大写字符集和小写字符集。这对 ASCII 来说是正确的,但在一般情况下必然如此

这和写类似

的原因是一样的
val = 10 * val + digitchar - '0';

当您编写代码将一串数字转换为相应的整数时。

“显而易见”的写法是

val = 10 * val + digitchar - 48;

但是那个神奇的数字 48 是从哪里来的呢?你必须在 ASCII 图表上查找它,如果我不熟悉它,我必须在 ASCII 图表上查找它才能弄清楚你的程序是如何工作的。如果您改为写入常量“0”,则可以节省我们双方的时间。 (顺便说一下,使用常量“0”意味着程序可以移植到使用 ASCII 以外的字符集的机器上,如果有人关心的话。)

类似地,如果我知道大写字母和小写字母的代码顺序相同但相隔一定数量,则使用计算 'A' - 'a' 来表示该数量再次更容易我和我的 reader 都比我去我的 ASCII 图表并计算出偏移量实际上是 32 时要多。

在这两种情况下,这里的原则是让机器来做脏活累活

我同意,一开始有点神秘。如果您习惯于在需要时在 ASCII 图表上查找内容,那么看到 'A' - 'a'digitchar - '0' 等奇怪的代码片段可能会让人迷失方向。不过,一旦您习惯了这些习语,它们就会 所以 容易得多,麻烦也少得多。

想想作者的观点,他们可能厌倦了在前面的页面上积累知识并介绍了 ASCII 码。他们还在较早的代码示例和段落中讨论了类型转换。对于初学者,作者试图让他们理解和交替使用 int 和 char。正如其他人所讨论的那样,它更干净。已经了解 C 编程的人可能会出现此问题。

在这种情况下我们也可以避免幻数32

c - 'A': 给出字母表中的字母编号;不在字符集中:

因此,例如,如果将 'A' 传递给 c - 'A',您将得到 0,因为所有被自身减去的内容都变为零;如果你通过 'B' 你得到 1;如果你通过 'C' 你得到 2 等等。你得到一个介于 0 到 25 之间的数字(英文字母包括 26 个字母,我们从 1 开始计算)

c - 'a': 让你的大写字母变成小写字母。它将您的字母编号放在字符集中的小写序列中。

例如,如果您通过 'A',您将获得 0;然后 0 + 'a' 给你字母 'a'。如果你通过 'B',你得到 1;然后 1 + 'a' 给你 'b' 紧跟在 'a' 之后。如果你通过 'C',你得到 2;然后 2 + 'a' 给你 'c' 这是 'a' 之后的两个字母等等。

还要考虑以下几点:

  • 看看 ASCII table。
  • 这个函数一般是针对顺序对应英文字母顺序的字符集设计的。其字符连续的字符集如:A、B、C、D...,其大小写字母为固定距离。