我有以下代码。如果我将control_word作为6,为什么如果条件求值为true并进入if if block?这里究竟发生了什么?
#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 */
}
}
答案 0 :(得分: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解释为“true或true”,并且产生true。
答案 1 :(得分: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==1
是false
,在算术表达式中被视为0 - 6==4
相同
((0 | 2) || (0 | 1 | 2)
是
2 || 3
是
true
因为2和3被视为true
(非零),因此您输入if
块,而不是else
要保留(假定的)意图(并获得你所表达的结果),你需要通过将它们的定义包装在括号中来保护宏的扩展 - 请注意,这是总是一个好主意避免你的想法和实际发生的事情之间的不和谐。