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,注意結果是常量。
這種平時習以為常的東西,不是什么大問題的東西,最容易讓人忽略。以后引以為戒。