移位不适用于变量声明赋值单行

Bit-shift not applying to a variable declaration-assignment one-liner

当我尝试在变量中应用右移位时,我看到了奇怪的行为 declaration/assignment:

unsigned int i = ~0 >> 1;

我得到的结果是 0xffffffff,就好像 >> 1 根本不存在一样。这似乎与 ~0 有关,因为如果我改为:

unsigned int i = 0xffffffff >> 1;

我按预期得到了 0x7fffffff。我以为我可能被运算符优先级问题绊倒了,所以尝试了:

unsigned int i = (~0) >> 1;

但这没什么区别。我可以在单独的语句中执行转换,比如

unsigned int i = ~0;
i >>= 1;

但我想知道发生了什么事。

更新 感谢 merlin2011 指出我的答案。原来它正在执行算术移位,因为它将 ~0 解释为有符号(负)值。最简单的修复似乎是:

unsigned int i = ~0u >> 1;

现在我想知道为什么 0xffffffff 没有也被解释为有符号值。

unsigned int i = ~0; 中,~0 被视为有符号整数(编译器应该对此发出警告)。

试试这个:

unsigned int i = (unsigned int)~0 >> 1;

这就是 c 编译器处理有符号值的方式。 C 中数字的基本文字是 int(在 32 位机器中,它是 32 位有符号 int

您可能希望将其更改为:

unsigned int i = ~(unsigned int)0 >> 1;

原因是因为对于带符号的值,编译器会将运算符 >> 视为算术移位(或 signed shift)。

或者,更简短(由 M.M 指出),

unsigned int i = ~0u >> 1;

测试:

printf("%x", i);

结果: