-3

今天我写了一个程序,但它有问题,所以我做了这个测试程序。好吧,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

为什么之后的输出MASK1完全MASK2不同? 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;
}
4

3 回答 3

6

您只是被宏是文本替换的事实所打动,而C 的优先规则就是它们。

这个:

num &= ~MASK2;

编译器会将其视为:

num &= ~0x3 << 16;

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

#define MASK2 (0x3 << 16)

永远不要将宏定义为表达式而不将其括在括号中,因为您不知道如何使用宏。

于 2013-08-15T10:05:49.050 回答
1

由于~具有比 更高的优先级<<,表达式

~0x3<<16

这是评估宏的结果

~MASK2

评估为:

(~0x3)<<16

而不是:

~(0x3<<16)

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

0x30000 == 0x3<<16

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

~0x30000 == ~0x3<<16 // FALSE -> ~0x3<<16 = (~0x3)<<16
于 2013-08-15T10:12:36.053 回答
0

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

#define MASK2 (0x3 << 16)
于 2013-08-15T10:06:20.743 回答