使用 ((c1^c2) & ~32) 测试 c1 和 c2 在不同情况下是否是相同的字符

use ((c1^c2) & ~32) to test if c1 and c2 are the same character in different case

我看到了这样的代码

if( ((c1^c2) & ~32)==0 )
{
  ...
}

在此代码段中,代码可能意味着如果 if 语句为真,则 c1c2 是相同的字符 在不同的情况下,这意味着其中一个与另一个相距 +32 或 -32。这是为什么?

我确实测试过自己,发现在某些情况下是正确的,而在其他情况下则不是:

printf("%d", (65^97)& ~32);   //output is 0. right
printf("%d", (97^65)& ~32);   //output is 0. right

printf("%d", (50^82)& ~32);   //output is 64!! not the same though 82-50=32

这是为什么?它有什么魔力?

(c1^c2) & ~32) xors c1c2,结果包含两个字符中的位,并且 &~32 清除(忽略) bit 5.(无论两者是否相同,都归零)。将其与零进行比较,检查 bit 5 以外的所有位是否相同。

如果您确定至少 c1c2 是有效的拉丁字符(a-z,A-Z),这可用于检查 2 个字母是否相等,忽略它们在 ascii 表示中的大小写。

为了理解这一点,让我们选择 2 个大小写不同的字符并进行比较:

       +---+---+---+---+---+---+---+---+
a      | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
       +---+---+---+---+---+---+---+---+
         |   x   |   |   |   |   |   |
       +---+---+---+---+---+---+---+---+
A      | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+
a ^ A  | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+
32     | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+
~32    | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
       +---+---+---+---+---+---+---+---+

       +---+---+---+---+---+---+---+---+
&      | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
       +---+---+---+---+---+---+---+---+

您可以尝试使用 j v/s Jt v/s z。 所以没有魔法,只有这个逻辑。

有时候这个条件也写成:

if (ch1 == ch2 || (ch1 ^ 32) == ch2)
{
  ...
}