2012-06-15 36 views
2

我有以下code.if我把control_word为6为什么如果条件评估为真,并进入内部,如果块?究竟发生了什么?为什么这个行为与MACRO?

#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 */ 
    } 

} 
+3

这不是关于宏的问题。你可以执行所有的替换,你会看到为什么你会得到这个结果。 –

回答

2

表达

control_word == MACRO3 || control_word == MACRO7 

扩展到

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

,最终扩展到

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

precedence table,可以看到运营商==具有优先级数字比|,这高于||,所以评价是:

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

计算结果为

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

,它是(6==1false,其在算术表达式视为0 - 同为6==4

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

这是

2 || 3 

true 

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

为了保持(推定)意图(和得到你所表达的结果)你需要通过将它们的定义放在圆括号中来保护宏的扩展 - 注意这是总是避免你的想法与实际发生的事情之间的不一致。

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解释为“真或真”,并且产生真实。

+0

是的,我同意括号可以解决这个问题。请你解释一下,如果它是如何进入的话,这里的确切行为是什么? – Sandeep

+2

它不是** _和_ || _之间的优先问题,它是_ == _和_ | _。看看这个[优先级图表](http://www.swansontec.com/sopc.html),并考虑将代码更改为:if((control_word == MACRO3)||(control_word == MACRO7) – pb2q

+0

已更正,请参阅更新。 – 2012-06-15 17:49:58