如何在 c 中计算 printf("%c\n",~('C'*-1)) ?

How printf("%c\n",~('C'*-1)) is computed in c?

#include<stdio.h>
int main()
{
printf("%c\n",~('C'*-1));
return 0;
}

上面的源码我已经试过了,没有任何警告就执行了。

输出为B。 我很兴奋上面的代码是如何处理的以及 printf("%c\n",~('C'*-1))

的含义是什么

在C语言中,'C'是一个int,它是一个小整数,值为67(假设为ASCII)。您可以从以下位置获取每个步骤:

#include<stdio.h>
int main()
{
    printf("%d\n", 'C');            //67
    printf("%d\n", 'C' * -1);       //-67
    printf("%d\n", ~('C' * - 1));   //66
    printf("%c\n",~('C' * -1));     //B
    return 0;
}

在2的补码中,~(-67)的值为66

唯一重要的部分是这个表达式:

~('C' * -1)

让我们分解一下:

  • 'C'ASCII 代码 67.
  • ('C' * -1) 是-67.
  • -67 在二进制中是 10111101
  • 按位取反(~),得到 01000010,即 66。
  • 66 是 'B'.
  • 的 ASCII 码

更一般地说,大多数计算机使用“two's complement”算术,其中数值取反后按位取反相当于减 1。当然 BC 少一在 ASCII 中。

在不使用补码运算的计算机上,结果可能会有所不同。这样的电脑很少见。

众所周知,"making a number negative"(将其乘以 -1)的二进制补码相当于反转其位表示形式 (~) 并加一 (+1).因此,上面等价于 ~(~'C' + 1),如果原始数字(如这里的 'C' 的 ASCII 代码)为奇数,则又相当于简单的递减。

即如果设置了'C'的LSB:

  • ~'C'的LSB没有设置,也就是说
  • 加一 (~'C' + 1) 后,LSB 再次设置。
  • 现在反转整个表达式 (~(~'C' + 1)) 将为我们提供原始数字 - 只是不再设置 LSB,因为它是在最终反转之前设置的(像其他位一样反转 LSB) .

同上简化一下

  • 'C' 十进制为 67,二进制为 01000011
  • ('C'*-1) 在十进制中是 -67 而在二进制中我们必须取 67 的补码 并在其补码中加 1 = 10111100 +1 = 10111101
  • ~('C'*-1) 是 -67 的否定,即 10111101 的恭维是 01000010 在十进制中是 66 在 ascii 中是 'B'