程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C說話高效編程的幾招小技能

C說話高效編程的幾招小技能

編輯:關於C++

C說話高效編程的幾招小技能。本站提示廣大學習愛好者:(C說話高效編程的幾招小技能)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話高效編程的幾招小技能正文


引言:

  編寫高效簡練的C說話代碼,是很多軟件工程師尋求的目的。本文就任務中的一些領會和經歷做相干的論述,纰謬的處所請列位指教。

第1招:以空間換時光

  盤算機法式中最年夜的抵觸是空間和時光的抵觸,那末,從這個角度動身逆向思想來斟酌法式的效力成績,我們就有懂得決成績的第1招——以空間換時光。

例如:字符串的賦值。
辦法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 ;

(應用的時刻可以直接用指針來操作。)

   從下面的例子可以看出,A和B的效力是不克不及比的。在異樣的存儲空間下,B直接應用指針便可以操作了,而A須要挪用兩個字符函數能力完成。B的缺陷在於靈 活性沒有A好。在須要頻仍更改一個字符串內容的時刻,A具有更好的靈巧性;假如采取辦法B,則須要預存很多字符串,固然占用了年夜量的內存,然則取得了法式 履行的高效力。

  假如體系的及時性請求很高,內存還有一些,那我推舉你應用該招數。

  該招數的變招——應用宏函數而不是函數。舉例以下:

辦法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);

   函數和宏函數的差別就在於,宏函數占用了年夜量的空間,而函數占用了時光。年夜家要曉得的是,函數挪用是要應用體系的棧來保留數據的,假如編譯器裡有棧檢討 選項,普通在函數的頭會嵌入一些匯編語句對以後棧停止檢討;同時,CPU也要在函數挪用時保留和恢復以後的現場,停止壓棧和彈棧操作,所以,函數挪用須要 一些CPU時光。而宏函數不存在這個成績。宏函數僅僅作為事後寫好的代碼嵌入到以後法式,不會發生函數挪用,所以僅僅是占用了空間,在頻仍挪用統一個宏函 數的時刻,該景象特別凸起。

  D辦法是我看到的最好的置位操作函數,是ARM公司源碼的一部門,在短短的三行內完成了許多功效,簡直涵蓋了一切的位操作功效。C辦法是其變體,個中味道還需年夜家細心領會。

第2招:數學辦法處理成績

  如今我們歸納高效C說話編寫的第二招——采取數學辦法來處理成績。

  數學是盤算機之母,沒稀有學的根據和基本,就沒有盤算機的成長,所以在編寫法式的時刻,采取一些數學辦法會對法式的履行效力稀有量級的進步。
舉例以下,求 1~100的和。
辦法E

int I , j;
for (I = 1 ;I<=100; I ++){
j += I;
}

辦法F

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

   這個例子是我印象最深的一個數學用例,是我的盤算機發蒙先生考我的。其時我只要小學三年級,惋惜我其時不曉得用公式 N×(N+1)/ 2 來處理這個成績。辦法E輪回了100次才處理成績,也就是說起碼用了100個賦值,100個斷定,200個加法(I和j);而辦法F僅僅用了1個加法,1 次乘法,1次除法。後果天然不問可知。所以,如今我在編法式的時刻,更多的是動頭腦找紀律,最年夜限制地施展數學的威力來進步法式運轉的效力。

第3招:應用位操作

  完成高效的C說話編寫的第三招——應用位操作,削減除法和取模的運算。

  在盤算機法式中,數據的位是可以操作的最小數據單元,實際上可以用“位運算”來完成一切的運算和操作。普通的位操作是用來掌握硬件的,或許做數據變換應用,然則,靈巧的位操作可以有用地進步法式運轉的效力。舉例以下:
辦法G

int I,J;
I = 257 /8;
J = 456 % 32;
辦法H
int I,J;
I = 257 >>3;
J = 456 - (456 >> 4 << 4);

   在字面上似乎H比G費事了很多多少,然則,細心檢查發生的匯編代碼就會明確,辦法G挪用了根本的取模函數和除法函數,既有函數挪用,還有許多匯編代碼和存放 器介入運算;而辦法H則僅僅是幾句相干的匯編,代碼更簡練,效力更高。固然,因為編譯器的分歧,能夠效力的差距不年夜,然則,以我今朝碰到的MS C ,ARM C 來看,效力的差距照樣不小。相干匯編代碼就不在這裡羅列了。
應用這招須要留意的是,由於CPU的分歧而發生的成績。好比說,在PC上用這招編寫的法式,並在PC上調試經由過程,在移植到一個16位機平台上的時刻,能夠會發生代碼隱患。所以只要在必定技巧進階的基本下才可使用這招。

第4招:匯編嵌入

  高效C說話編程的必殺技,第四招——嵌入匯編。

  “在熟習匯編說話的人眼裡,C說話編寫的法式都是渣滓”。這類說法固然過火了一些,然則卻有它的事理。匯編說話是效力最高的盤算機說話,然則,弗成能靠著它來寫一個操作體系吧?所以,為了取得法式的高效力,我們只好采取變通的辦法 ——嵌入匯編,混雜編程。

  舉例以下,將數組一賦值給數組二,請求每字節都符合。

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

   辦法I是最多見的辦法,應用了1024次輪回;辦法J則依據平台分歧做了辨別,在ARM平台下,用嵌入匯編僅用128次輪回就完成了異樣的操作。這裡有 同伙會說,為何不消尺度的內存拷貝函數呢?這是由於在源數據裡能夠含稀有據為0的字節,如許的話,尺度庫函數會提早停止而不會完成我們請求的操作。這個 例程典范運用於LCD數據的拷貝進程。依據分歧的CPU,闇練應用響應的嵌入匯編,可以年夜年夜進步法式履行的效力。

  固然是必殺技,然則假如隨意馬虎應用會支付沉重的價值。這是由於,應用了嵌入匯編,便限制了法式的可移植性,使法式在分歧平台移植的進程中,臥虎藏龍,險象環生!同時該招數也與古代軟件工程的思惟相違反,只要在必不得已的情形下才可以采取。切記,切記。

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