位移时的 C 奇怪行为

标签 c bit-manipulation

为什么以下使用 gcc 编译的代码打印出“ffffffff 0”而不是“0 0”?在两条指令中,这些位都向右移动了 32 个位置。这没有多大意义,因为 x == 32,但仍然会发生这种奇怪的结果......

#include <stdio.h>

int main(void)
{
    int x = 32;
    printf("%x\n", 0xffffffff >> x);
    printf("%x\n", 0xffffffff >> 32);
    return 0;
}

编辑: enter image description here

编辑2: 是的,编译器警告我。但这不是重点。我使用 0xffffffff 作为掩码,我用一个变量进行位移。例如,当我用 8 进行位移时,我想要 0xffffff(它就是这样做的)。当我用 31 进行位移时,我想要 0x1 作为结果(它就是这样做的)。当我用 32 进行位移时,它会给我 0xffffffff(而不是 0,这是当我将 32 作为文字而不是变量时的行为)。这很奇怪,为了我的目的,为 32 做一个特例真的很不方便,因为它应该给出 0(它确实给出了,但只有当 32 是一个字面值时)

最佳答案

假设 int 和 unsigned int 都是 32 位宽,整数常量 0xffffffff 是 unsigned int 类型。

右移一个值大于或等于整数宽度的整数将导致未定义的行为1

在您的示例中,这两种情况都会发生。

更新:

未定义的行为意味着任何事情都可能发生。获取值 0xffffffff 而不是 0 符合此行为。

你不能移动整数类型的宽度,因为它在标准中是这样说的。您必须检查该值是否大于或等于您使用的类型的宽度。


1(引自:ISO/IEC 9899:201x 6.5.7 移位运算符 3)
如果右操作数的值为负或大于或等于提升后的左操作数的宽度,则行为未定义。

关于位移时的 C 奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40239766/

相关文章:

c - 需要帮助理解 K&R C 第 2 章中的 "getbits()"方法

不能在 C 中使用延迟/ sleep 函数

c - 编译linux内核报 'make: *** [modules_install] Error 1'错误如何解决?

c - 使用 While 循环打印模式并且仅使用 C 中的三个输出语句

c - 按行与按列访问矩阵元素

c - 在 8 位 PIN 中设置一位而不更改其他位

c - 如何使用popen同时输入和输出?

c - 集体分配给一个结构体

bit-manipulation - 如何在WinDbg中使用ba命令(Break on Access)?

ruby - 逐位检查整数(获取和设置)