« 上一篇下一篇 »

操作符优先级问题

我们先来看一条代码:

// 如果P2.10FEI位为1,表明中断由P2.10口下降沿产生
if( LPC_GPIOINT->IO2IntStatF & 0x00000400 != 0 )
{
  GPIO_ToggleBits(LPC_GPIO2, GPIO_Pin_0);          // LED取反,表明进入了该中断
}

代码的意思很明了,即如果“!=”操作符左边的表达式的值不等于0的话,则此判断语句为真,紧跟着执行之后的代码块,但事实并非如此,因为在“LPC_GPIOINT->IO2IntStatF”的值为0x00000400的情况下,花括号内的代码仍然没有执行,这表明此时if()内的表达式为假,而按照我们之前的想法,如果“LPC_GPIOINT->IO2IntStatF”的值为0x00000400,则有:0x00000400 & 0x00000400 = 0x00000400,这个值不等于0,if()内表达式应该为真,而事实却刚好相反,那么问题出在哪里呢?

优先级!操作符优先级!翻开《C和指针》,找到操作符的优先级表,顿时一切就明了了,下图为操作符优先级表的一部分(从上到下优先级递减)。

从图中可以看出,“!=”的优先级高于“&”,接下来我们再来看一看前面的if()表达式,因为“!=”优先级高于“&”,所以表达式先执行“0x00000400 != 0”这一部分,结果为1,接着就是“LPC_GPIOINT->IO2IntStatF & 1”,即“0x00000400 & 1”,其结果为0,故if()内表达式为假,所以不执行花括号内语句。

现在已经找到问题所在了,那么该如何修改呢?根据前面所述,我们必须使得“!=”操作符左边的表达式的求值要先于之后的不等于比较,所以就可以使用“()”来修改优先级,修改后的if()表达式如下:

// 如果P2.10FEI位为1,表明中断由P2.10口下降沿产生
if( (LPC_GPIOINT->IO2IntStatF & 0x00000400) != 0 )

或者干脆去掉“ != 0”,即

// 如果P2.10FEI位为1,表明中断由P2.10口下降沿产生
if( LPC_GPIOINT->IO2IntStatF & 0x00000400 )

好了,最后总结一下:如果你需要进行等于或不等于比较,则“==”“!=”操作符左边的表达式的最外层尽量加上一个括号将其整个括住,以保证左边的表达式先进行求值,尤其是在左边表达式中含有“&”“^”“|”“&&”“||”等位操作符或逻辑操作符的情况下。

另:身边应该要有一本必备工具书,如《C和指针》,你可以不完全记得操作符的优先级或是其他基础知识,但是你要保证能够随时进行查看