当我们用2字节数进行4字节数的AND运算时会发生什么

时间:2017-12-08 04:00:12

标签: c bit-manipulation bitwise-operators

我正在尝试编写一段代码来从4字节整数中提取每个字节的数据 经过一点点的搜索,我实际上找到了可以实现这一目的的代码,但我只是想知道为什么它的行为与输出的创建方式有关,下面是代码

#include <stdio.h>

int getByte(int x, int n);

void main()
{
    int x = 0xAABBCCDD;
    int n;

    for (n=0; n<=3; n++) {
        printf("byte %d of 0x%X is 0x%X\n",n,x,getByte(x,n));
    }

}

// extract byte n from word x
// bytes numbered from 0 (LSByte) to 3 (MSByte)
int getByte(int x, int n)
{
    return (x >> (n << 3)) & 0xFF;
}

输出:

byte 0 of 0xAABBCCDD is 0xDD
byte 1 of 0xAABBCCDD is 0xCC
byte 2 of 0xAABBCCDD is 0xBB
byte 3 of 0xAABBCCDD is 0xAA

结果是自解释的,但为什么编译器没有将0xFF转换为0x000000FF,因为它必须用4字节数执行AND操作,而是生成仅包含1字节数据而不是4字节数据的输出

3 个答案:

答案 0 :(得分:4)

编译器确实将0xFF转换为0x000000FF。由于该值是整数常量,因此0xFF在内部转换为32位值(假设您的平台具有32位int)。

请注意,您获得的值,即0xDD0xCC0xBB0xAA,也是int s,因此它们具有领先优势也是零,所以你实际上得到了0x000000DD0x000000CC,等等。但是,前导零不会自动打印,因此如果您希望看到它们,则需要更改格式字符串以请求包含前导零:

for (n=0; n<=3; n++) {
    printf("byte %d of 0x%08X is 0x%08X\n", n, x, getByte(x,n));
}

Demo.

答案 1 :(得分:3)

输出 是一个4字节的数字,但printf("%X")不会打印任何前导零位数。

如果您执行printf("foo 0x%X bar\n", 0x0000AA),那么您将获得foo 0xAA bar作为输出。

答案 2 :(得分:1)

0xFF和0x000000FF都是完全相同的,默认情况下,如果你想在输出中打印它们,格式化会丢弃前导0,你只需要指定它:

printf("byte %d of 0x%X is 0x08%X\n",n,x,getByte(x,n));

但是既然你正在打印Bytes我不太清楚为什么你会期待领先的0。