程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 手把手教你若何優化C說話法式

手把手教你若何優化C說話法式

編輯:關於C++

手把手教你若何優化C說話法式。本站提示廣大學習愛好者:(手把手教你若何優化C說話法式)文章只能為提供參考,不一定能成為您想要的結果。以下是手把手教你若何優化C說話法式正文


1、法式構造的優化

1、法式的書寫構造
固然書寫格局其實不會影響生成的代碼質量,然則在現實編寫法式時照樣應當尊循必定的書寫規矩,一個書寫清楚、清楚明了的法式,有益於今後的保護。在書寫法式時,特殊是關於While、for、do…while、if…elst、switch…case等語句或這些語句嵌套組應時,應采取“縮格”的書寫情勢,

2、標識符
法式中應用的用戶標識符除要遵守標識符的定名規矩之外,普通不要用代數符號(如a、b、x1、y1)作為變量名,應拔取具有相干寄義的英文單詞(或縮寫)或漢語拼音作為標識符,以增長法式的可讀性,如:count、number1、red、work等。

3、法式構造
C說話是一種高等法式設計說話,供給了非常完整的標准化流程掌握構造。是以在采取C說話設計單片機運用體系法式時,起首要留意盡量采取構造化的法式設計辦法,如許可以使全部運用體系法式構造清楚,便於調試和保護。於一個較年夜的運用法式,平日將全部法式按功效分紅若干個模塊,分歧模塊完成分歧的功效。各個模塊可以分離編寫,乃至還可以由分歧的法式員編寫,普通單個模塊完成的功效較為簡略,設計和調試也絕對輕易一些。在C說話中,一個函數便可以以為是一個模塊。所謂法式模塊化,不只是要將全部法式劃分紅若干個功效模塊,更主要的是,還應當留意堅持各個模塊之間變量的絕對自力性,即堅持模塊的自力性,盡可能少應用全局變量等。關於一些經常使用的功效模塊,還可以封裝為一個運用法式庫,以便須要時可以直接挪用。然則在應用模塊化時,假如將模塊分紅太細太小,又會招致法式的履行效力變低(進入和加入一個函數時掩護和恢復存放器占用了一些時光)。

4、界說常數
在法式化設計進程中,關於常常應用的一些常數,假如將它直接寫到法式中去,一旦常數的數值產生變更,就必需逐一找出法式中一切的常數,並一一停止修正,如許必定會下降法式的可保護性。是以,應盡可能當采取預處置敕令方法來界說常數,並且還可以免輸出毛病。

5、削減斷定語句
可以或許應用前提編譯(ifdef)的處所就應用前提編譯而不應用if語句,有益於削減編譯生成的代碼的長度,可以或許不消斷定語句則罕用斷定用語句。

6、表達式
關於一個表達式中各類運算履行的優先次序不太明白或輕易混雜的處所,應該采取圓括號明白指定它們的優先次序。一個表達式平日不克不及寫得太龐雜,假如表達式太龐雜,時光久了今後,本身也不輕易看得懂,晦氣於今後的保護。

7、函數
關於法式中的函數,在應用之前,應對函數的類型停止解釋,對函數類型的解釋必需包管它與本來界說的函數類型分歧,關於沒有參數和沒有前往值類型的函數應加上“void”解釋。假如果須要延長代碼的長度,可以將法式中一些公共的法式段界說為函數,在Keil中的高等別優化就是如許的。假如須要延長法式的履行時光,在法式調試停止後,將部門函數用宏界說來取代。留意,應當在法式調試停止後再界說宏,由於年夜多半編譯體系在宏睜開以後才會報錯,如許會增長排錯的難度。

8、盡可能罕用全局變量,多用部分變量。
由於全局變量是放在數據存儲器中,界說一個全局變量,MCU就少一個可以應用的數據存儲器空間,假如界說了太多的全局變量,會招致編譯器無足夠的內存可以分派。而部分變量年夜多定位於MCU外部的存放器中,在絕年夜多半MCU中,應用存放器操作速度比數據存儲器快,指令也更多更靈巧,有益於生成質量更高的代碼,並且部分變量所的占用的存放器和數據存儲器在分歧的模塊中可以反復應用。

9、設定適合的編譯法式選項
很多編譯法式有幾種分歧的優化選項,在應用前應懂得各優化選項的寄義,然後選用最適合的一種優化方法。平日情形下一旦選用第一流優化,編譯法式會近乎病態地尋求代碼優化,能夠會影響法式的准確性,招致法式運轉失足。是以應熟習所應用的編譯器,應曉得哪些參數在優化時會遭到影響,哪些參數不會遭到影響。
在ICCAVR中,有“Default”和“Enable Code Compression”兩個優化選項。
在CodeVisionAVR中,“Tiny”和“small”兩種內存形式。
在IAR中,共有7種分歧的內存形式選項。
在GCCAVR中優化選項更多,一不當心更輕易選到不適當的選項。

2、代碼的優化

1、選擇適合的算法和數據構造
應當熟習算法說話,曉得各類算法的優缺陷,詳細材料請拜見響應的參考材料,有許多盤算機書本上都有引見。將比擬慢的次序查找法用較快的二分查找或亂序查找法取代,拔出排序或冒泡排序法用疾速排序、歸並排序或根排序取代,都可以年夜年夜進步法式履行的效力。.選擇一種適合的數據構造也很主要,好比你在一堆隨機寄存的數中應用了年夜量的拔出和刪除指令,那應用鏈表要快很多。
數組與指針語句具有非常暗碼的關系,普通來講,指針比擬靈巧簡練,而數組則比擬直不雅,輕易懂得。關於年夜部門的編譯器,應用指針比應用數組生成的代碼更短,履行效力更高。然則在Keil中則相反,應用數組比應用的指針生成的代碼更短。。

3、應用盡可能小的數據類型
可以或許應用字符型(char)界說的變量,就不要應用整型(int)變量來界說;可以或許應用整型變量界說的變量就不要用長整型(long int),能不應用浮點型(float)變量就不要應用浮點型變量。固然,在界說變量後不要跨越變量的感化規模,假如跨越變量的規模賦值,C編譯器其實不報錯,但法式運轉成果卻錯了,並且如許的毛病很難發明。
在ICCAVR中,可以在Options中設定應用printf參數,盡可能應用根本型參數(%c、%d、%x、%X、%u和%s格局解釋符),罕用長整型參數(%ld、%lu、%lx和%lX格局解釋符),至於浮點型的參數(%f)則盡可能不要應用,其它C編譯器也一樣。在其它前提不變的情形下,應用%f參數,會使生成的代碼的數目增長許多,履行速度下降。

4、應用自加、自減指令
平日應用自加、自減指令和復合賦值表達式(如a-=1及a+=1等)都可以或許生成高質量的法式代碼,編譯器平日都可以或許生成inc和dec之類的指令,而應用a=a+1或a=a-1之類的指令,有許多C編譯器都邑生成二到三個字節的指令。在AVR單片實用的ICCAVR、GCCAVR、IAR等C編譯器以上幾種書寫方法生成的代碼是一樣的,也可以或許生成高質量的inc和dec之類的的代碼。

5、削減運算的強度
可使用運算量小但功效雷同的表達式調換本來龐雜的的表達式。以下:

(1)、求余運算。
     a=a%8;
可以改成:
     a=a&7;
解釋:位操作只需一個指令周期便可完成,而年夜部門的C編譯器的“%”運算均是挪用子法式來完成,代碼長、履行速度慢。平日,只需求是求2n方的余數,都可應用位操作的辦法來取代。

(2)、平方運算
     a=pow(a,2.0);
可以改成:
     a=a*a;
解釋:在有內置硬件乘法器的單片機中(如51系列),乘法運算比求平方運算快很多,由於浮點數的求平方是經由過程挪用子法式來完成的,在自帶硬件乘法器的AVR單片機中,如ATMega163中,乘法運算只需2個時鐘周期便可以完成。既使是在沒有內置硬件乘法器的AVR單片機中,乘法運算的子法式比平方運算的子法式代碼短,履行速度快。

假如是求3次方,如:
     a=pow(a,3.0);
更改成:
     a=a*a*a;
則效力的改良更顯著。

(3)、用移位完成乘除法運算
     a=a*4;
     b=b/4;
可以改成:
     a=a<<2;
     b=b>>2;
解釋:平日假如須要乘以或除以2n,都可以用移位的辦法取代。在ICCAVR中,假如乘以2n,都可以生成左移的代碼,而乘以其它的整數或除以任何數,均挪用乘除方法法式。用移位的辦法獲得代碼比挪用乘除方法法式生成的代碼效力高。現實上,只需是乘以或除以一個整數,都可以用移位的辦法獲得成果,如:
     a=a*9
可以改成:
     a=(a<<3)+a

6、輪回
(1)、輪回語
     關於一些不須要輪回變量加入運算的義務可以把它們放到輪回裡面,這裡的義務包含表達式、函數的挪用、指針運算、數組拜訪等,應當將沒有需要履行屢次的操作全體聚集在一路,放到一個init的初始化法式中停止。

(2)、延時函數:
     平日應用的延時函數均采取自加的情勢:
     void delay (void)
     {
unsigned int i;
     for (i=0;i<1000;i++)

     }
將其改成自減延時函數:
     void delay (void)
     {
unsigned int i;
         for (i=1000;i>0;i--)

     }
兩個函數的延時後果類似,但簡直一切的C編譯對後一種函數生成的代碼均比前一種代碼少1~3個字節,由於簡直一切的MCU均無為0轉移的指令,采取後一種方法可以或許生成這類指令。
在應用while輪回時也一樣,應用自減指令掌握輪回會比應用自加指令掌握輪回生成的代碼更少1~3個字母。
然則在輪回中有經由過程輪回變量“i”讀寫數組的指令時,應用預減輪回時有能夠使數組超界,要惹起留意。

(3)while輪回和do…while輪回
用while輪回時有以下兩種輪回情勢:
unsigned int i;
     i=0;
     while (i<1000)
     {
         i++;
    //用戶法式
     }
或:
unsigned int i;
     i=1000;
     do
     i--;
     //用戶法式
     while (i>0);
在這兩種輪回中,應用do…while輪回編譯後生成的代碼的長度短於while輪回。

7、查表
在法式中普通不停止異常龐雜的運算,如浮點數的乘除及開方等,和一些龐雜的數學模子的插補運算,對這些即消費時光又花費資本的運算,應盡可能應用查表的方法,而且將數據表置於法式存儲區。假如直接生成所需的表比擬艱苦,也盡可能在啟動時先盤算,然後在數據存儲器中生成所需的表,後以在法式運轉直接查表便可以了,削減了法式履行進程中反復盤算的任務量。

8、其它
好比應用在線匯編及將字符串和一些常量保留在法式存儲器中,均有益於優化。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved