2

我有以下代码。如果我将 control_word 设为 6,为什么 if 条件评估为 true 并进入 if 块?这里到底发生了什么?

#define MACRO1 0x01
#define MACRO2 0x02
#define MACRO4 0x04
#define MACRO3 MACRO1 | MACRO2
#define MACRO7 MACRO4 | MACRO3

int main()
{
    if(control_word == MACRO3 || control_word == MACRO7)
    {
        /*DO SOME OPERATION*/
    }
    else
    {
        /*DO SOMETHING ELSE */
    }

}
4

2 回答 2

11

| 的优先级 和 == 运算符并不是您认为的那样。道德:总是用括号括起来你的宏!

#define MACRO3 (MACRO1 | MACRO2)
#define MACRO7 (MACRO4 | MACRO3)

所以会发生什么是表达式扩展为

control_word == 0x01 | 0x02 || control_word == 0x01 | 0x02  | 0x04

反过来形成

(control_word == 1) | 2 || (control_word == 7) | 6)

那是

0 | 2 || 0 | 6

所以总而言之

2 || 6

这被 C 解释为“真或真”,结果为真。

于 2012-06-15T17:45:08.880 回答
2

表达方式

control_word == MACRO3 || control_word == MACRO7

扩展到

control_word == MACRO1 | MACRO2 || control_word == MACRO4 | MACRO3

最终扩展到

control_word == 1 | 2 || control_word == 4 | 1 | 2

查看优先级表,您会看到运算符的优先级==高于|,高于||,因此评估为:

((control_word == 1) | 2) || ((control_word == 4) | 1 | 2)

评估为

((6 == 1) | 2) || ((6 == 4) | 1 | 2)

这是 ( 6==1is false,在算术表达式中被视为 0 - 与 相同6==4)

((0 | 2) || (0 | 1 | 2)

这是

2 || 3

这是

true

因为 2 和 3 被视为true(非零),所以你进入if块,而不是else

为了保持(假定的)意图(并获得您期望的结果),您需要通过将宏的定义包装在括号中来保护宏的扩展 - 请注意,这始终是避免您的想法和想法之间不和谐的好主意实际上正在发生。

于 2012-06-15T17:51:42.543 回答