c-为什么相同的逐位操作会产生不同的结果



试图在所有其他位打开的情况下关闭MSB。

unsigned char a = ~0 << 1 >> 1;
printf("a: %dn", a);
unsigned char b = ~0;
b <<= 1;
b >>= 1;
printf("b: %dn", b);

打印输出给出:

a: 255
b: 127

适用整数提升规则。

对每个操作数执行整数提升。结果的类型是提升后的左操作数。

初始化的RHS:

unsigned char a = ~0 << 1 >> 1;

0转换为int,然后进行逐位左移和右移,最后赋值将结果转换为unsigned char。这意味着结果将是255(假设CHAR_BIT == 8)。从技术上讲,您有未定义的行为

E1 << E2的结果是E1左移位的E2位位置;空出的位用零。如果E1具有无符号类型,则结果的值为E1×2E2,减约模比结果类型中可表示的最大值多一个。如果E1有签名类型和非负值,并且E1×2E2在结果类型中是可表示的,那么结果值;否则,行为是未定义的。

如果你使用,你可以避免未定义的行为

unsigned char a = ~0U << 1 >> 1;

"多重分配"版本(避免未定义的行为)相当于:

unsigned char a = (unsigned char)(~0U << 1) >> 1;

其在重新提升用于右移的类型之前截断左移的结果并且将产生127作为结果(仍然假设CHAR_BIT == 8)。

相关内容

  • 没有找到相关文章

最新更新