为什么使用位掩码0x30000给出的结果与使用0x3<< 16?

时间:2013-08-15 10:00:27

标签: c

今天我写了一个程序,但它有问题,所以我做了这个测试程序。好吧,0x30000等于0x3 << 16,不是吗?

在这个程序中,它表明0x30000在开始时等于0x3 << 16,但最后,这个程序给了我完全不同的结果!我不知道为什么,这个结果是如此奇怪!

输出结果为:

MASK1
0000 0000 0000 0011 0000 0000 0000 0000
MASK2
0000 0000 0000 0011 0000 0000 0000 0000
equal!!!!!
Before 1
0000 0000 0001 0010 1101 0110 1000 0111
After 1
0000 0000 0001 0000 1101 0110 1000 0111
Before 2
0000 0000 0001 0010 1101 0110 1000 0111
After 2
0000 0000 0001 0000 0000 0000 0000 0000

为什么MASK1MASK2之后的输出完全不同? MASK1做了正确的事,但MASK2似乎出了问题。为什么我会得到这些结果?

#include <stdio.h>
#include <string.h>

#define MASK1 0x30000
#define MASK2 0x3 << 16

void show_binary(unsigned long n);

void change_alignment(unsigned long *s);
void eatline(void);
int main(void)
{
    unsigned long   num;
    puts("MASK1");
    show_binary(MASK1);
    puts("MASK2");
    show_binary(MASK2);
    num = 1234567;

    if(MASK1 == MASK2)
        puts("equal!!!!!");
    puts("Before 1");
    show_binary(num);
    num &= ~MASK1;
    puts("After 1");
    show_binary(num);

    num = 1234567;
    puts("Before 2");

    show_binary(num);
    num &= ~MASK2;
    puts("After 2");
    show_binary(num);

    return 0;
}

void show_binary(unsigned long n)
{
    unsigned long   mask = 1;
    int     size = sizeof(unsigned long) * 8;
    char        bin[size + 1];
    int         index = 0;

    bin[size] = '\0';

    while(size > 0)
    {
        if((mask & n) == mask)
            bin[size - 1] = '1';
        else
            bin[size - 1] = '0';

        mask <<= 1;
        size--;
    }

    while(bin[index])
    {
        putchar(bin[index]);
        if(++index % 4 == 0 && bin[index])
            putchar(' ');
    }
    putchar('\n');
}

void eatline(void)
{
    while(getchar() != '\n')
        continue;
}

3 个答案:

答案 0 :(得分:6)

您只是简单地认识到宏是文本替换,而C's precendence rules就是它们。

此:

num &= ~MASK2;

将被编译器视为:

num &= ~0x3 << 16;

这不是你的意思(因为~比转变更紧密,它被评估为(~3) << 16)。您必须在宏中添加括号:

#define MASK2 (0x3 << 16)

一个人应该从不将宏定义为表达式而不将其括在括号中,因为你不知道如何使用宏。

答案 1 :(得分:1)

由于~的优先级高于<<,因此表达式

~0x3<<16

这是评估宏

的结果
~MASK2

评估为:

(~0x3)<<16

而不是:

~(0x3<<16)

因此,当以下情况属实时(手动执行宏替换时):

0x30000 == 0x3<<16

由于==的优先级低于<<,因此以下内容不是:

~0x30000 == ~0x3<<16 // FALSE -> ~0x3<<16 = (~0x3)<<16

答案 2 :(得分:0)

我想你忘记了一个括号:试试

#define MASK2 (0x3 << 16)