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

标签 c operators

我看到了一些这样的代码

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)异或c1c2 ,结果包含字符和 & 中的位与 ~32清除(忽略)第 5 位。(无论两者是否相同,都将其归零)。将其与零进行比较,检查是否除 bit 5 之外的所有位是一样的。

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

为了理解这一点,让我们选择 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)
{
  ...
}

关于c - 使用 ((c1^c2) & ~32) 测试 c1 和 c2 在不同情况下是否是相同的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31018335/

相关文章:

c - 如何使用 Windows MessageBox() C 函数?

c - 微 Controller 的sprintf和printf有什么区别

c - 谁将数字转换为 2 的补码形式并存储在内存位置?

c - lirpm - 如何验证已安装包的签名 key

c - *p 和 *&p 有什么区别

javascript - 这个 es6 赋值运算符是什么?

c++如何定义不复制数据的强制转换运算符?

c# - 有什么区别 |和 ||还是运营商?

c++ - 转换时的意外行为

c - 如何使用可以远程连接的控制台创建 linux C 应用程序