C语言中关于三目运算符的注意事项

      C语言中常见的条件运算符?:在运算符优先级中排行13。部分时候可以代替if……else语句,使代码更加简洁。但是更容易隐含一些不易觉察的错误。

      最近接了一个项目,本来通信协议部分很简单,自己的STM32控制器通过中断方式接收帧数据,每帧23个字节,其中前4个字节是帧头(校验的关键字)。结果就在这里出现了错误,而且这个小小的错误花费了一天时间来查找。对于一个周期很紧的项目来说,在这种小问题上花费这么长时间代价可谓不小。写此贴以警醒自己曾经犯得错误,也希望偶尔看到的朋友可以避免同样的错误。

      1、三目运算符定义

      condition ? expression1 : expression2

      expression1和expression2是两个操作数。如果condition = true,则结果为expression1,否则为expression2.

      2、项目中利用三目运算符进行帧头判断时出现的问题

     

 1 if(CountFlag == 0)       //Frame head 0xAA
 2         {
 3             CountFlag = ((unsigned char)UsartReceiveData[CountFlag] != 0xAA)? 0 : CountFlag++;
 4             //        CountFlag = (ReceiveData != 0xAA)? 0 : CountFlag++;
 5             // if((unsigned char)UsartReceiveData[CountFlag] == 0xAA)
 6             // {
 7                 // CountFlag++;
 8             // }
 9             // else
10             // {
11                 // CountFlag = 0;
12             // }
13             
14         }            
15         else if(CountFlag == 1)  //Frame head 0xAA

      CountFlag为变量(帧字节位置计数变量),定义为unsigned int类型。

      本意为了避免注释中的if……else结构代码行数过多,而采用了三目运算符结构,代码的结构和逻辑均非常简单。但是意想不到的事情发生了。

      无论从机发送的帧头数据正确还是错误,程序只执行CountFlag == 0这一种情况。why? 百思不得其解。

      如果采用注释中的的if……else结构则数据收发正确,说明问题就出在三目运算符表达语句上。然后专门写了一个三目运算符的测试程序。调试发现按照这种结构,即使if语句为真,该语句也不执行?看了几遍也没有发现逻辑错误。问度娘也没有找到有价值的参考。

      将CountFlag++改写为CountFlag + 1,则结果正确。至此问题已经找到答案。

      3、错误原因

      CountFlag++的结果仍然是一个变量,假设初值为0,执行完后表达式的值即CountFlag变量的值为1,这个值1存放在CountFlag变量中。

      CountFlag + 1的结果是一个常量,    假设初值为0,执行完后表达式的值即值为1,注意结果是常量。

      这种平时习以为常的东西,不是什么大问题的东西,最容易让人忽略。以后引以为戒。

原文地址:https://www.cnblogs.com/guojingdeyuan/p/6171454.html