尝试在所有其他位打开的情况下关闭MSB。
unsigned char a = ~0 << 1 >> 1;
printf("a: %d\n", a);
unsigned char b = ~0;
b <<= 1;
b >>= 1;
printf("b: %d\n", b);
打印输出给出:
a: 255
b: 127
答案 0 :(得分:3)
适用整数促销规则。
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。
初始化的RHS:
unsigned char a = ~0 << 1 >> 1;
将0
转换为int
,然后按位左右移位,最后分配将结果转换为unsigned char
。这意味着结果将是255(假设为CHAR_BIT == 8
)。从技术上讲,您有未定义的行为:
E1 << E2
的结果是E1
左移E2
位位置;腾出的位充满了 零。如果E1
具有无符号类型,则结果的值为E1×2 E2 ,减少模数 比结果类型中可表示的最大值多一个。如果E1有签名 类型和非负值,E1×2 E2 在结果类型中可表示,那么 结果价值;否则,行为未定义。
如果您使用了以下内容,则可以避免未定义的行为:
unsigned char a = ~0U << 1 >> 1;
“多个分配”版本(避免未定义的行为)等同于:
unsigned char a = (unsigned char)(~0U << 1) >> 1;
在重新提升右移的类型之前截断左移的结果,结果将产生127(仍然假设为CHAR_BIT == 8
)。