單片機C語言易錯知識點,記住它們會讓你事半功倍!
在進行單片機開發時,經常都會出現一些很不起眼的問題,這些問題其實都是很基礎的C語言知識點,是一些小細節。
但是正是因為很基礎,又都是小細節,所以我們往往容易忽視它們。結果有時候我們會花很長的時間糾結一個問題,遲遲找不到問題的所在。當發現原因竟然是這么的簡單和不起眼時,我想不單是我,大家都會感到痛不欲生。這些問題要記錄下來,時刻提醒自己!!
1、 !和 ~ 不一樣! 是邏輯非符號,~ 是位取反符號。對IO口某個引腳賦值時不要錯用 !如
2、<<和>>的優先級低于+、-比如要實現c=x*2+1,沒有加括號會出錯
3、移位要防止溢出其實用移位代替乘除法是個不錯的方法,筆者很喜歡拿到一段代碼后用移位代替乘除法來進行優化。不過有時候卻會出現問題,比如溢出問題。當很明顯可能溢出的話我們是會注意的,比如但是有時候這個問題是不明顯的,比如當移位出現在數組索引或函數參數時,有段用液晶顯示字符的代碼如下
我們可以用左移運算來代替乘法進行優化,如
這本是一個好方法,但是事實上上面的代碼是錯的。當執行c<<4時,因為沒有明顯的賦值過程,我們可能認為沒問題,而事實上c的高位已經丟失了,所以得到錯誤的結果。一個可行的做法是先進行強制轉換,如
4、無符號數和有符號數混合運算都會被強制轉換為無符號數運算當一個有符號數和一個無符號數進行算術運算時,系統會自動將有符號數強制轉換為無符號數再進行運算(即使你使用有符號數強制類型轉換),如下面兩種寫法的運輸結果是一樣的
5、局部變量要初始化局部變量沒有初始化的話,因為單片機每次為他分配的是同一個內存區域,當你在函數中是這么使用局部變量時,就可能出問題:如果第一次調用fun時,a傳遞的值為0,那么flag = 0x01;執行if(flag&0x01)后面的代碼。以后再調用fun時,即使a不為0,但flag依然使用之前的內存區域,所以其值一直為0x01,一直執行的是if后面的代碼,而不是else后面的。 |