寫(xiě)單片機(jī)程序數(shù)據(jù)類(lèi)型相關(guān)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
最近在調(diào)試單片機(jī)程序,總是遇到一些開(kāi)始認(rèn)為不可思議的事情,后來(lái)解決了問(wèn)題后發(fā)現(xiàn),都是因?yàn)樽约簳?shū)寫(xiě)程序不嚴(yán)謹(jǐn),其主要原因是沒(méi)有注意c語(yǔ)言的數(shù)據(jù)類(lèi)型的數(shù)據(jù)范圍。
對(duì)有符號(hào)、無(wú)符號(hào)數(shù)據(jù)的使用存在誤區(qū),對(duì)類(lèi)型轉(zhuǎn)換理解不到位。下面就舉例一一說(shuō)明:
1:一個(gè)簡(jiǎn)單的for循環(huán),但因?yàn)閿?shù)據(jù)溢出導(dǎo)致進(jìn)入死循環(huán),無(wú)法實(shí)現(xiàn)相應(yīng)功能。
unsigned char i;
for(i=0;i<256;i++)
語(yǔ)句;
咋看起來(lái)這語(yǔ)句沒(méi)有什么問(wèn)題。但仔細(xì)考慮發(fā)現(xiàn),i在此循環(huán)中會(huì)溢出,i的值 0---255---0----255----0-----------。
2:在循環(huán)里還需要注意的是有符號(hào)數(shù)和無(wú)符號(hào)數(shù)進(jìn)行比較時(shí):
unsigned char i;
i=230;
if(i>-5)
當(dāng)無(wú)符號(hào)和有符號(hào)數(shù)進(jìn)行比較時(shí),會(huì)把無(wú)符號(hào)數(shù)轉(zhuǎn)換為有符號(hào)數(shù),i=230轉(zhuǎn)換成有符號(hào)數(shù)是-26 因此if條件不成立。
3:使用printf或sprintf時(shí),注意要打印的數(shù)值的數(shù)據(jù)類(lèi)型,否則打印出來(lái)的不是你需要的。
4:注意在各個(gè)函數(shù)參數(shù)或者其他賦值時(shí)的數(shù)據(jù)類(lèi)型的默認(rèn)轉(zhuǎn)換。考慮清楚的類(lèi)型不匹配時(shí),和默認(rèn)類(lèi)型轉(zhuǎn)換不符時(shí),可以使用強(qiáng)制類(lèi)型轉(zhuǎn)換。
5:昨天調(diào)試一個(gè)單片機(jī)漢字顯示程序時(shí),遇到數(shù)據(jù)簡(jiǎn)單運(yùn)算結(jié)果不對(duì)的情況。
uchar ch0,ch1;
uint32offset;
offset=(uint32) (HZ_BASE_ADDR+((((ch0 - 1) * 94) + (ch1 - 1))*32)); 這個(gè)語(yǔ)句算出的結(jié)果不對(duì),開(kāi)始不理解,后來(lái)發(fā)現(xiàn)還是數(shù)據(jù)類(lèi)型的問(wèn)題。原因是ch0是無(wú)符號(hào)字符類(lèi)型的,因此((ch0 - 1) * 94) 的結(jié)果溢出。導(dǎo)致出錯(cuò)。修正方案:offset=(uint32) (HZ_BASE_ADDR+((((ch0 - 1) * 94L) + (ch1 - 1))*32L)); 添加強(qiáng)制轉(zhuǎn)換,把立即數(shù)強(qiáng)制為long int型數(shù)據(jù),根據(jù)c語(yǔ)言默認(rèn)數(shù)據(jù)類(lèi)型提升方案,其他參與運(yùn)算的數(shù)值也轉(zhuǎn)換為long int型。問(wèn)題解決。