單片機(jī)C語(yǔ)言優(yōu)化
雖然并不會(huì)影響生成代碼的質(zhì)量,但是在實(shí)際編寫過(guò)程中還是要遵循一定的書寫規(guī)則,一個(gè)書寫清晰明了的程序有利于以后的維護(hù)。在書寫程序時(shí),特別是對(duì)于while、for、do while、if else、switch case等語(yǔ)句或這些語(yǔ)句嵌套組合時(shí),應(yīng)采用“縮格”的書寫形式。
本文引用地址:http://www.ex-cimer.com/article/201611/316913.htm二、標(biāo)識(shí)符
程序種使用的用戶標(biāo)識(shí)符除要遵循標(biāo)識(shí)符的命名規(guī)則以外,一半不要用代數(shù)符號(hào)(如a、b、x1、x2)作為變量名,應(yīng)選取具有相關(guān)含義的英文單詞(或縮寫)或拼音作為標(biāo)識(shí)符,增加程序的可讀性。
三、程序結(jié)構(gòu)
C語(yǔ)言是一種高級(jí)程序設(shè)計(jì)語(yǔ)言,提供了十分完備的規(guī)范化流程控制結(jié)構(gòu)。因此在采用C語(yǔ)言設(shè)計(jì)單片機(jī)應(yīng)用程序時(shí),首先要注意盡可能采用結(jié)構(gòu)化的程序設(shè)計(jì)方法。這樣可以使應(yīng)用系統(tǒng)程序結(jié)構(gòu)清晰便于調(diào)試和維護(hù)。對(duì)于一個(gè)較大的應(yīng)用程序,通常將整個(gè)程序按功能分成若干個(gè)模塊,不同的模塊完成不同的功能。各個(gè)模塊可以分別編寫,甚至還可以由不同的程序員編寫。一半單個(gè)模塊完成的功能較為簡(jiǎn)單,設(shè)計(jì)和調(diào)試也相對(duì)容易一些。在C語(yǔ)言中一個(gè)函數(shù)就可以認(rèn)為是一個(gè)模塊。所謂程序模塊化。不僅是要將整個(gè)程序劃分成若干個(gè)功能模塊。更重要的是,還應(yīng)該保持各個(gè)模塊之間變量的相對(duì)獨(dú)立性。盡量少使用全局變量等。對(duì)于一些常用的功能模塊還可以封裝為一個(gè)應(yīng)用程序庫(kù),以便需要時(shí)可以直接調(diào)用。但是在使用模塊化時(shí),如果將模塊分的太細(xì)又會(huì)導(dǎo)致程序的執(zhí)行效率低(今天和和推出一個(gè)函數(shù)時(shí)需要保護(hù)和恢復(fù)寄存器占用的了一些時(shí)間)。
四、定義常熟
在程序化設(shè)計(jì)過(guò)程中,對(duì)于經(jīng)常使用的一些常數(shù),如果將它直接寫到程序中去,一旦常數(shù)的數(shù)值發(fā)生變化,就必須逐個(gè)找出程序中所有的常數(shù),并逐一進(jìn)行修改,這樣必然會(huì)導(dǎo)致降低程序的可維護(hù)性。因此,應(yīng)盡量當(dāng)采用與處理命令的方式來(lái)定義常數(shù)。而且還可以避免輸入錯(cuò)誤。
五、減少判斷語(yǔ)句
能夠使用條件編譯的(ifdef)的地方就使用條件編譯而不使用(if)語(yǔ)句有利于減少編譯生成的代碼的長(zhǎng)度。
六、表達(dá)式
對(duì)于一個(gè)表達(dá)式中的運(yùn)算執(zhí)行的優(yōu)先順序不太明確或容易混淆的地方,應(yīng)當(dāng)采用圓括號(hào)明確制定它們的順序。一個(gè)表達(dá)式不能寫得太復(fù)雜。如果太復(fù)雜,時(shí)間久了以后自己也不容易看的懂,不易于以后的維護(hù)。
七、函數(shù)
對(duì)于程序中的函數(shù),在使用之前,應(yīng)對(duì)函數(shù)的類型進(jìn)行說(shuō)明,對(duì)函數(shù)類型的說(shuō)明,必須保證它與原來(lái)定義的函數(shù)類型一致,對(duì)于沒有參數(shù)和沒用返回值的函數(shù)應(yīng)加上void說(shuō)明。如果需要縮短代碼的長(zhǎng)度,可以將程序中一些公共的程序段定義為函數(shù)。在keil中搞級(jí)別優(yōu)化就是這樣的。如果需要縮短程序的執(zhí)行時(shí)間。在程序調(diào)試結(jié)束后,將部分函數(shù)用宏定義來(lái)代替。注意,應(yīng)該在程序調(diào)試結(jié)束后再定義宏,因?yàn)榇蠖鄶?shù)編譯系統(tǒng)在宏展開之后才會(huì)報(bào)錯(cuò),這樣會(huì)增加排錯(cuò)的難度。
八、變量
盡量少使用全局變量多用局部變量。因?yàn)槿肿兞渴欠旁跀?shù)據(jù)存儲(chǔ)器中,定義一個(gè)全局變量,mcu就少一個(gè)可以利用的數(shù)據(jù)存儲(chǔ)空間。如果定義了太多的全局變量,會(huì)導(dǎo)致編譯器無(wú)足夠的內(nèi)存可以分配。而局部變量大多定位于mcu內(nèi)部的寄存器中。在絕大多數(shù)mcu中使用寄存器操作速度比數(shù)據(jù)寄存器塊。質(zhì)量也更多更靈活。有利于生成高質(zhì)量的代碼。而且局部變量所占用的寄存器和數(shù)據(jù)存儲(chǔ)器在不同模塊中可以重復(fù)使用。
九、代碼的優(yōu)化
選擇和漢斯的算法和數(shù)據(jù)結(jié)構(gòu),應(yīng)該熟悉算法語(yǔ)言,知道各種算法的優(yōu)缺點(diǎn),具體資料請(qǐng)參見相應(yīng)的參考資料,又很多計(jì)算機(jī)書籍上都又介紹。將比較慢的順序查找法用比較快的二分查找或亂序查找法代替。插入排序或冒泡排序法用快速排序、合并排序或跟排序代替。都可以大大提高程序執(zhí)行的效率。選擇一種合適的數(shù)據(jù)結(jié)構(gòu)也很重要。必然你在一堆隨機(jī)存放的數(shù)中使用了大量的插入和排序指令,那使用鏈表要快的多。
使用盡量小的數(shù)據(jù)類型
能夠使用字符型(char)定義的變量就不要使用整形(int)變量來(lái)定義
使用自加、自減指令
減少運(yùn)算強(qiáng)度
可以使用運(yùn)算量小丹功能相同的表達(dá)式替換原來(lái)復(fù)雜的表達(dá)式:
如求余運(yùn)算
a=a%8
可以改為:a=a&7
平方運(yùn)算
a=pow(a,2.0);
可以改為:a=a*a;
用移位運(yùn)算實(shí)現(xiàn)乘除法
a=a*4
b=b/4
可以改為:
a=a<<2
b=b>>2
a=a*9可以改為a=(a<<3)+a;
循環(huán)
對(duì)于一些不需要循環(huán)變量參加運(yùn)算的任務(wù)把它們安排的循環(huán)外面。這里任務(wù)包括表達(dá)式、函數(shù)的調(diào)用、指針運(yùn)算、數(shù)組訪問(wèn)等,應(yīng)該將沒有必要執(zhí)行多次的操作全部集合在一起,放到一個(gè)init的初始化程序中進(jìn)行。
延時(shí)函數(shù):
通常使用的延時(shí)函數(shù):
void delay(void)
{
unsigned int i;
for(i=0;i<1000;i++);
}
改為
void dellay(void)
{
unsigned int i;
for(i=1000;--i)
}
兩個(gè)函數(shù)效果相似,但幾乎所有的C編譯器對(duì)后一種函數(shù)生成的代碼比前一種代碼少1-3個(gè)字節(jié)。因?yàn)閹缀跛蠱CU都有0轉(zhuǎn)移指令采用后一種方式能夠生成這類指令。在while循環(huán)時(shí)也一樣,使用自減指令控制循環(huán)比使用自加指令控制循環(huán)生成代碼少1-3個(gè)字節(jié)。在使用while循環(huán)中又使用循環(huán)變量讀寫數(shù)據(jù)的指令時(shí),使用減循環(huán)時(shí)又可能是數(shù)組超界,要引起注意。
while、和do while循環(huán)
unsigned int i;
i=0;
while(i<1000)
{
i++;
}
改為
do
i--;
while(i>0);
在這兩種循環(huán)中,使用do while循環(huán)編譯后的代碼長(zhǎng)度短于while循環(huán)。
查表
在程序中一般不進(jìn)行非常復(fù)雜的運(yùn)算,如浮點(diǎn)數(shù)的程序及開方等。以及一些復(fù)雜的數(shù)學(xué)模型的插補(bǔ)運(yùn)算。對(duì)這些即消耗時(shí)間又消耗資源的運(yùn)算。應(yīng)盡量使用查表的方式,并且將數(shù)據(jù)表置于程序存儲(chǔ)區(qū)。如果直接生成所需的表比較困難。也盡量在啟動(dòng)時(shí)先計(jì)算。然后在數(shù)據(jù)存儲(chǔ)器中生成所需要的表。在程序運(yùn)行中直接查表就可以了。減少了程序執(zhí)行過(guò)程中重復(fù)計(jì)算的工作量。
其他
比如使用在線匯編及字符串和一些常量的保存在程序存儲(chǔ)器中都又利于優(yōu)化。
評(píng)論