單片機(jī)C語(yǔ)言易錯(cuò)知識(shí)點(diǎn)經(jīng)驗(yàn)筆記
今天寫這一篇文章并不是因?yàn)橐呀?jīng)想好了一篇文章才寫下來(lái),而是我要將這一篇文章作為一篇筆記來(lái)寫,一直更新下去。在進(jìn)行單片機(jī)開發(fā)時(shí),經(jīng)常都會(huì)出現(xiàn)一些很不起眼的問題,這些問題其實(shí)都是很基礎(chǔ)的c語(yǔ)言知識(shí)點(diǎn),是一些小細(xì)節(jié)。但是正是因?yàn)楹芑A(chǔ),又都是小細(xì)節(jié),所以我們往往容易忽視它們。結(jié)果有時(shí)候我們會(huì)花很長(zhǎng)的時(shí)間糾結(jié)一個(gè)問題,遲遲找不到問題的所在。當(dāng)發(fā)現(xiàn)原因竟然是這么的簡(jiǎn)單和不起眼時(shí),我想不單是我,大家都會(huì)感到痛不欲生。筆者今天又碰到了這樣的問題,實(shí)在忍不住了。因?yàn)檫@些問題都是小的知識(shí)點(diǎn),考慮到之前也遇到好多這種問題,于是決定每次遇到問題就記錄下來(lái),時(shí)刻提醒自己!!
1. !和 ~ 不一樣
! 是邏輯非符號(hào),~ 是位取反符號(hào)。
對(duì)IO口某個(gè)管腳賦值時(shí)不要錯(cuò)用 !,如
2.<<和>>的優(yōu)先級(jí)低于+、-
比如要實(shí)現(xiàn)c=x*2+1,沒有加括號(hào)會(huì)出錯(cuò)
3.移位要防止溢出
其實(shí)用移位代替乘除法是個(gè)不錯(cuò)的方法,筆者很喜歡拿到一段代碼后用移位代替乘除法來(lái)進(jìn)行優(yōu)化。不過(guò)有時(shí)候卻會(huì)出現(xiàn)問題,比如溢出問題。當(dāng)很明顯可能溢出的話我們是會(huì)注意的,比如
但是有時(shí)候這個(gè)問題是不明顯的,比如當(dāng)移位出現(xiàn)在數(shù)組索引或函數(shù)參數(shù)時(shí),有段用液晶顯示字符的代碼如下
我們可以用左移運(yùn)算來(lái)代替乘法進(jìn)行優(yōu)化,如
這本是一個(gè)好方法,但是事實(shí)上上面的代碼是錯(cuò)的。當(dāng)執(zhí)行c<<4時(shí),因?yàn)闆]有明顯的賦值過(guò)程,我們可能認(rèn)為沒問題,而事實(shí)上c的高位已經(jīng)丟失了,所以得到錯(cuò)誤的結(jié)果。一個(gè)可行的做法是先進(jìn)行強(qiáng)制轉(zhuǎn)換,如
4.無(wú)符號(hào)數(shù)和有符號(hào)數(shù)混合運(yùn)算都會(huì)被強(qiáng)制轉(zhuǎn)換為無(wú)符號(hào)數(shù)運(yùn)算
當(dāng)一個(gè)有符號(hào)數(shù)和一個(gè)無(wú)符號(hào)數(shù)進(jìn)行算術(shù)運(yùn)算時(shí),系統(tǒng)會(huì)自動(dòng)將有符號(hào)數(shù)強(qiáng)制轉(zhuǎn)換為無(wú)符號(hào)數(shù)再進(jìn)行運(yùn)算(即使你使用有符號(hào)數(shù)強(qiáng)制類型轉(zhuǎn)換),如下面兩種寫法的運(yùn)輸結(jié)果是一樣的
5.局部變量要初始化
局部變量沒有初始化的話,因?yàn)閱纹瑱C(jī)每次為他分配的是同一個(gè)內(nèi)存區(qū)域,當(dāng)你在函數(shù)中是這么使用局部變量時(shí),就可能出問題:
如果第一次調(diào)用fun時(shí),a傳遞的值為0,那么flag = 0x01;執(zhí)行if(flag&0x01)后面的代碼。以后再調(diào)用fun時(shí),即使a不為0,但flag依然使用之前的內(nèi)存區(qū)域,所以其值一直為0x01,一直執(zhí)行的是if后面的代碼,而不是else后面的。
如果要避免這個(gè)錯(cuò)誤,平時(shí)要養(yǎng)成對(duì)局部變量初始化的習(xí)慣。





