一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看

C語(yǔ)言

如何優(yōu)化C代碼

時(shí)間:2025-03-28 04:57:21 C語(yǔ)言 我要投稿
  • 相關(guān)推薦

如何優(yōu)化C代碼

  C代碼規則繁多,使用靈活,容易出錯,教師教學(xué)和學(xué)生學(xué)習都感到困難,而到后期學(xué)生能真正編寫(xiě)程序時(shí),代碼繁瑣,下面是小編為大家搜索整理的如何優(yōu)化C代碼,希望能給大家帶來(lái)幫助!更多精彩內容請及時(shí)關(guān)注我們應屆畢業(yè)生考試網(wǎng)!

  第一招:以空間換時(shí)間

  計算機程序中最大的矛盾是空間和時(shí)間的矛盾,那么,從這個(gè)角度出發(fā)逆向思維來(lái)考慮程序的效率問(wèn)題,我們就有了解決問(wèn)題的第1招--以空間換時(shí)間。比如說(shuō)字符串的賦值:

  方法A:通常的辦法

  #define LEN 32

  char string1 [LEN];

  memset (string1,0,LEN);

  strcpy (string1,"This is a example!!");

  方法B:

  const char string2[LEN] ="This is a example!";

  char * cp;

  cp = string2 ;

  使用的時(shí)候可以直接用指針來(lái)操作。

  從上面的例子可以看出,A和B的效率是不能比的。在同樣的存儲空間下,B直接使用指針就可以操作了,而A需要調用兩個(gè)字符函數才能完成。B的缺點(diǎn)在于靈活性沒(méi)有A好。在需要頻繁更改一個(gè)字符串內容的時(shí)候,A具有更好的靈活性;如果采用方法B,則需要預存許多字符串,雖然占用了大量的內存,但是獲得了程序執行的高效率。

  如果系統的實(shí)時(shí)性要求很高,內存還有一些,那我推薦你使用該招數。

  第二招: 使用宏而不是函數。

  這也是第一招的變招。函數和宏的區別就在于,宏占用了大量的空間,而函數占用了時(shí)間。大家要知道的是,函數調用是要使用系統的棧來(lái)保存數據的,如果編譯器里有棧檢查選 項,一般在函數的頭會(huì )嵌入一些匯編語(yǔ)句對當前棧進(jìn)行檢查;同時(shí),CPU也要在函數調用時(shí)保存和恢復當前的現場(chǎng),進(jìn)行壓棧和彈棧操作,所以,函數調用需要一 些CPU時(shí)間。 而宏不存在這個(gè)問(wèn)題。宏僅僅作為預先寫(xiě)好的代碼嵌入到當前程序,不會(huì )產(chǎn)生函數調用,所以?xún)H僅是占用了空間,在頻繁調用同一個(gè)宏的時(shí)候,該現象尤其突出。

  舉例如下:

  方法C:

  #define bwMCDR2_ADDRESS 4

  #define bsMCDR2_ADDRESS 17

  int BIT_MASK(int __bf)

  {

  return ((1U << (bw ## __bf)) - 1)<< (bs ## __bf);

  }

  void SET_BITS(int __dst,

  int __bf, int __val)

  {

  __dst = ((__dst) & ~(BIT_MASK(__bf))) |

  (((__val) << (bs ## __bf))

  & (BIT_MASK(__bf))))

  }

  SET_BITS(MCDR2, MCDR2_ADDRESS,ReGISterNumber);

  方法D:

  #define bwMCDR2_ADDRESS 4

  #define bsMCDR2_ADDRESS 17

  #define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)

  #define BIT_MASK(__bf)

  (((1U << (bw ## __bf)) - 1)

  << (bs ## __bf))

  #define SET_BITS(__dst, __bf, __val)

  ((__dst) = ((__dst) & ~(BIT_MASK(__bf)))

  |

  (((__val) << (bs ## __bf))

  & (BIT_MASK(__bf))))

  SET_BITS(MCDR2, MCDR2_ADDRESS,

  RegisterNumber);

  D方法是我看到的最好的置位操作函數,是arm公司源碼的一部分,在短短的三行內實(shí)現了很多功能,幾乎涵蓋了所有的位操作功能。C方法是其變體,其中滋味還需大家仔細體會(huì )。

  第三招:數學(xué)方法解決問(wèn)題

  現在我們演繹高效C語(yǔ)言編寫(xiě)的第二招--采用數學(xué)方法來(lái)解決問(wèn)題。數學(xué)是計算機之母,沒(méi)有數學(xué)的依據和基礎,就沒(méi)有計算機的發(fā)展,所以在編寫(xiě)程序的時(shí)候,采用一些數學(xué)方法會(huì )對程序的執行效率有數量級的提高。舉例如下,求 1~100的和。

  方法E:

  int I , j;

  for (I = 1 ;I<=100; I ++)

  {

  j += I;

  }

  方法F

  int I;

  I = (100 * (1+100)) / 2

  這個(gè)例子是我印象最深的一個(gè)數學(xué)用例,是我的計算機啟蒙老師考我的。當時(shí)我只有小學(xué)三年級,可惜我當時(shí)不知道用公式 N×(N+1)/ 2 來(lái)解決這個(gè)問(wèn)題。方法E循環(huán)了100次才解決問(wèn)題,也就是說(shuō)最少用了100個(gè)賦值,100個(gè)判斷,200個(gè)加法(I和j);而方法F僅僅用了1個(gè)加法,1 次乘法,1次除法。效果自然不言而喻。所以,現在我在編程序的時(shí)候,更多的是動(dòng)腦筋找規律,最大限度地發(fā)揮數學(xué)的威力來(lái)提高程序運行的效率。

  第四招:使用位操作

  使用位操作。減少除法和取模的運算。在計算機程序中數據的位是可以操作的最小數據單位,理論上可以用"位運算"來(lái)完成所有的運算和操作。一般的位操作是用來(lái)控制硬件的,或者做數據變換使用,但是,靈活的位操作可以有效地提高程序運行的效率。舉例如下:

  方法G

  int I,J;

  I = 257 /8;

  J = 456 % 32;

  方法H

  int I,J;

  I = 257 >>3;

  J = 456 - (456 >> 4 << 4);

  在字面上好像H比G麻煩了好多,但是,仔細查看產(chǎn)生的匯編代碼就會(huì )明白,方法G調用了基本的取模函數和除法函數,既有函數調用,還有很多匯編代碼和寄存器參與運算;而方法H則僅僅是幾句相關(guān)的匯編,代碼更簡(jiǎn)潔,效率更高。當然,由于編譯器的不同,可能效率的差距不大,但是,以我目前遇到的MS C ,arm C 來(lái)看,效率的差距還是不小。

  對于以2的指數次方為"*"、"/"或"%"因子的數學(xué)運算,轉化為移位運算"<< >>"通?梢蕴岣咚惴ㄐ。因為乘除運算指令周期通常比移位運算大。

  C語(yǔ)言位運算除了可以提高運算效率外,在嵌入式系統的編程中,它的另一個(gè)最典型的應用,而且十分廣泛地正在被使用著(zhù)的是位間的與(&)、或(|)、非(~)操作,這跟嵌入式系統的編程特點(diǎn)有很大關(guān)系。我們通常要對硬件寄存器進(jìn)行位設置,譬如,我們通過(guò)將AM186ER型80186處理器的中斷屏蔽控制寄存器的第低6位設置為0(開(kāi)中斷2),最通用的做法是:

  #define INT_I2_MASK 0x0040

  wTemp = inword(INT_MASK);

  outword(INT_MASK, wTemp &~INT_I2_MASK);

  而將該位設置為1的做法是:

  #define INT_I2_MASK 0x0040

  wTemp = inword(INT_MASK);

  outword(INT_MASK, wTemp | INT_I2_MASK);

  判斷該位是否為1的做法是:

  #define INT_I2_MASK 0x0040

  wTemp = inword(INT_MASK);

  if(wTemp & INT_I2_MASK)

  {

  … /* 該位為1 */

  }

  運用這招需要注意的是,因為CPU的不同而產(chǎn)生的問(wèn)題。比如說(shuō),在PC上用這招編寫(xiě)的程序,并在PC上調試通過(guò),在移植到一個(gè)16位機平臺上的時(shí)候,可能會(huì )產(chǎn)生代碼隱患。所以只有在一定技術(shù)進(jìn)階的基礎下才可以使用這招。

  第五招:匯編嵌入

  在熟悉匯編語(yǔ)言的人眼里,C語(yǔ)言編寫(xiě)的程序都是垃圾"。這種說(shuō)法雖然偏激了一些,但是卻有它的道理。匯編語(yǔ)言是效率最高的計算機語(yǔ)言,但是,不可能靠著(zhù)它來(lái)寫(xiě)一個(gè)操作系統吧?所以,為了獲得程序的高效率,我們只好采用變通的方法--嵌入匯編,混合編程。嵌入式C程序中主要使用在線(xiàn)匯編,即在C程序中直接插入_asm{ }內嵌匯編語(yǔ)句。

  舉例如下,將數組一賦值給數組二,要求每一字節都相符。

  char string1[1024],string2[1024];

  方法I

  int I;

  for (I =0 ;I<1024;I++)

  *(string2 + I) = *(string1 + I)

  方法J

  #ifdef _PC_

  int I;

  for (I =0 ;I<1024;I++)

  *(string2 + I) = *(string1 + I);

  #else

  #ifdef _arm_

  __asm

  {

  MOV R0,string1

  MOV R1,string2

  MOV R2,#0

  loop:

  LDMIA R0!, [R3-R11]

  STMIA R1!, [R3-R11]

  ADD R2,R2,#8

  CMP R2, #400

  BNE loop

  }

  #endif

  再舉個(gè)例子:

  /* 把兩個(gè)輸入參數的值相加,結果存放到另外一個(gè)全局變量中 */

  int result;

  void Add(long a, long *b)

  {

  _asm

  {

  MOV AX, a

  MOV BX, b

  ADD AX, [BX]

  MOV result, AX

  }

  }

  方法I是最常見(jiàn)的方法,使用了1024次循環(huán);方法J則根據平臺不同做了區分,在arm平臺下,用嵌入匯編僅用128次循環(huán)就完成了同樣的操作。這里有朋友會(huì )說(shuō),為什么不用標準的內存拷貝函數呢?這是因為在源數據里可能含有數據為0的字節,這樣的話(huà),標準庫函數會(huì )提前結束而不會(huì )完成我們要求的操作。這個(gè)例程典型應用于LCD數據的拷貝過(guò)程。根據不同的CPU,熟練使用相應的嵌入匯編,可以大大提高程序執行的效率。

  雖然是必殺技,但是如果輕易使用會(huì )付出慘重的代價(jià)。這是因為,使用了嵌入匯編,便限制了程序的可移植性,使程序在不同平臺移植的過(guò)程中,臥虎藏龍,險象環(huán)生!同時(shí)該招數也與現代軟件工程的思想相違背,只有在迫不得已的情況下才可以采用。

  第六招, 使用寄存器變量

  當對一個(gè)變量頻繁被讀寫(xiě)時(shí),需要反復訪(fǎng)問(wèn)內存,從而花費大量的存取時(shí)間。為此,C語(yǔ)言提供了一種變量,即寄存器變量。這種變量存放在CPU的寄存器中,使用時(shí),不需要訪(fǎng)問(wèn)內存,而直接從寄存器中讀寫(xiě),從而提高效率。寄存器變量的說(shuō)明符是register。對于循環(huán)次數較多的循環(huán)控制變量及循環(huán)體內反復使用的變量均可定義為寄存器變量,而循環(huán)計數是應用寄存器變量的最好候選者。

  (1) 只有局部自動(dòng)變量和形參才可以定義為寄存器變量。因為寄存器變量屬于動(dòng)態(tài)存儲方式,凡需要采用靜態(tài)存儲方式的量都不能定義為寄存器變量,包括:模塊間全局變量、模塊內全局變量、局部static變量;

  (2) register是一個(gè)"建議"型關(guān)鍵字,意指程序建議該變量放在寄存器中,但最終該變量可能因為條件不滿(mǎn)足并未成為寄存器變量,而是被放在了存儲器中,但編譯器中并不報錯(在C++語(yǔ)言中有另一個(gè)"建議"型關(guān)鍵字:inline)。

  下面是一個(gè)采用寄存器變量的例子:

  /* 求1+2+3+….+n的值 */

  WORD Addition(BYTE n)

  {

  register i,s=0;

  for(i=1;i<=n;i++)

  {

  s=s+i;

  }

  return s;

  }

  本程序循環(huán)n次,i和s都被頻繁使用,因此可定義為寄存器變量。

  第七招: 利用硬件特性

  首先要明白CPU對各種存儲器的訪(fǎng)問(wèn)速度,基本上是:

  CPU內部RAM > 外部同步RAM > 外部異步RAM > FLASH/ROM

  對于程序代碼,已經(jīng)被燒錄在FLASH或ROM中,我們可以讓CPU直接從其中讀取代碼執行,但通常這不是一個(gè)好辦法,我們最好在系統啟動(dòng)后將FLASH或ROM中的目標代碼拷貝入RAM中后再執行以提高取指令速度;

  對于UART等設備,其內部有一定容量的接收BUFFER,我們應盡量在BUFFER被占滿(mǎn)后再向CPU提出中斷。例如計算機終端在向目標機通過(guò)RS-232傳遞數據時(shí),不宜設置UART只接收到一個(gè)BYTE就向CPU提中斷,從而無(wú)謂浪費中斷處理時(shí)間;

  如果對某設備能采取DMA方式讀取,就采用DMA讀取,DMA讀取方式在讀取目標中包含的存儲信息較大時(shí)效率較高,其數據傳輸的基本單位是塊,而所傳輸的數據是從設備直接送入內存的(或者相反)。DMA方式較之中斷驅動(dòng)方式,減少了CPU 對外設的干預,進(jìn)一步提高了CPU與外設的并行操作程度。

【如何優(yōu)化C代碼】相關(guān)文章:

c語(yǔ)言空間換時(shí)間優(yōu)化代碼的方法10-10

c語(yǔ)言空間換時(shí)間優(yōu)化代碼的技巧方法06-19

如何優(yōu)化C程序性能04-27

PHP代碼優(yōu)化技巧09-10

JAVA代碼優(yōu)化總結09-23

如何優(yōu)化C語(yǔ)言(單片機)06-01

PHP調用的C代碼08-05

C語(yǔ)言精簡(jiǎn)代碼10-03

如何提高單片機C語(yǔ)言代碼效率10-30

一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看