C语言有32个关键字,却有34个运算符。要记住所有运算符的优先级是困难的。稍不注意,你的代码逻辑和实际执行就会有很大出入。
比如下面将BCD码转换为十六进制数的代码:
result=(uTimeValue>>4)*10+uTimeValue&0x0F;
这里uTimeValue存放的BCD码,想要转换成16进制数据,实际运行发现,如果uTimeValue的值为0x23,按照我设定的逻辑,result的值应该是0x17,但运算结果却是0x07。经过种种排查后,才发现’+’的优先级是大于’&’的,相当于(uTimeValue>>4)*10+uTimeValue与0x0F位与,结果自然与逻辑不符。符合逻辑的代码应该是:
result=(uTimeValue>>4)*10+(uTimeValue&0x0F);
不合理的#define会加重优先级问题,让问题变得更加隐蔽。
编译器在编译后将宏带入,原代码语句变为:
if(IO0PIN&(1<<11) ==(1<<11))
{
//其它代码
}
运算符'=='的优先级是大于'&'的,代码IO0PIN&(1<<11) ==(1<<11))等效为IO0PIN&0x00000001:判断端口P0.0是否为高电平,这与原意相差甚远。因此,使用宏定义的时候,最好将被定义的内容用括号括起来。
按照常规方式使用时,可能引起误会的运算符还有很多,如下表所示。C语言的运算符当然不会只止步于数目繁多!
有一个简便方法可以避免优先级问题:不清楚的优先级就加上”()”,但这样至少有会带来两个问题:
过多的括号影响代码的可读性,包括自己和以后的维护人员
别人的代码不一定用括号来解决优先级问题,但你总要读别人的代码
无论如何,在嵌入式编程方面,该掌握的基础知识,偷巧不得。建议花一些时间,将优先级顺序以及容易出错的优先级运算符理清几遍。
|