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