为什么按位运算符(~)的序列会是这样?那是坏了吗?

Why the sequence from the bitwise operator(~) would be this? Is that broken?

#include <stdio.h>
#include <stdlib.h>

int main() {
unsigned char a=100,b=50;

printf("%d & %d = %d\n",a,b,a&b);
printf("%d | %d = %d\n",a,b,a|b);
printf("%d ^ %d = %d\n",a,b,a^b);
printf(" ~%d = %d\n",a, ~a);       /*the out come of this  line would be this: ~100 = -101 */
printf(" %d >> 2= %d\n",a, a>>2);
printf(" %d << 2= %d\n",a, a<<2);
system("pause");
return 0;
}

/结果应该是155吧?/

100 = 0x64
~0x64 = 0x9B

printf(" ~%d = %d\n",a, ~a);中,第二个格式说明符%d需要一个signed integer,因此结果0x9B将被扩展为一个signed integer0x9B的MSB为1,所以认为是negative value.

0x9B ---extends to>>> 0xFFFFFF9B = -101

如果您希望结果为 155,您需要一个 unsigned 转换,这样 0x9B 将扩展为 0x0000009B

#include <stdio.h>

int main() {
  unsigned char a = 100, b = 50;

  printf(" ~%d = %d\n", a, ~a);
  printf(" ~%d = %d\n", a, (unsigned char)~a);

  return 0;
}

这将给出结果:

gcc test.c
./a.out

 ~100 = -101
 ~100 = 155

按照标准,~的操作数会进行整数提升。所以这里我们先把a提升为int.

[expr.unary.op]: The operand of ~ shall have integral or unscoped enumeration type; the result is the ones' complement of its operand. Integral promotions are performed.

如果int是4个字节(例如),提升后的a的值为0x00000064~a的结果是0xFFFFFF9B,正好是-101(如果用补码表示整数)。

请注意,虽然可变参数会进行整数提升,但这里的 ~aint 类型,不需要额外提升。