《 C 語(yǔ)言的一些“騷操作”及其深層理解》之memcpy 的效率
memcpy的效率
memcpy函數(shù)的功能是用來(lái)作內(nèi)存搬運(yùn),就是將數(shù)據(jù)從一個(gè)數(shù)組賦值到另一個(gè)數(shù)組。它的實(shí)現(xiàn)很簡(jiǎn)單:
但是這種實(shí)現(xiàn)方式,其實(shí)是比較膚淺而低效的。作為嵌入式或硬件工程師,如果對(duì)上面的代碼看不出什么問(wèn)題的話,那可能要好好找找自身的原因。
上面的代碼,對(duì)CPU數(shù)據(jù)總線帶寬的利用率不高,我們把它改成這樣:
改進(jìn)后的代碼最大限度的利用了CPU數(shù)據(jù)總線帶寬,每次傳輸多個(gè)字節(jié)(如32位平臺(tái)為4字節(jié))。這一實(shí)例告訴我們:C語(yǔ)言,尤其是嵌入式C語(yǔ)言很多時(shí)候需要考慮硬件層面的因素,如CPU總線、內(nèi)存結(jié)構(gòu)等。
[]的本質(zhì)
當(dāng)我們想取出一個(gè)數(shù)組中的某個(gè)元素時(shí),我們會(huì)用到[],采用下標(biāo)的方式。如下例:
int a[3]={1,2,3};
a[1]; //數(shù)組a的第2個(gè)元素
其實(shí)我們可以用其它方式取出這個(gè)元素,即*(a+1)??梢钥吹絒]與*,在功能上有相似之處。其實(shí)[]并不限于與數(shù)組搭配訪問(wèn)數(shù)組元素,它的實(shí)質(zhì)是:訪問(wèn)以指針?biāo)赶虻牡刂窞殚_(kāi)始地址,以其下標(biāo)為偏移量的存儲(chǔ)單元中的數(shù)據(jù),如圖2.12所示。
圖2.12 []的實(shí)質(zhì)其實(shí)就是所謂的“基址偏移量取值”
上圖可能顛覆了一些人對(duì)[]的認(rèn)識(shí),下標(biāo)還能是負(fù)數(shù)?[]可以在一個(gè)開(kāi)始地址后面去取數(shù)據(jù),為什么不能在它前面取數(shù)據(jù)呢?我們可以理解[]是對(duì)指針加減和取值操作的綜合。
認(rèn)清了[]的實(shí)質(zhì),再加上對(duì)C語(yǔ)言的精髓--指針深刻的理解,我們編程將會(huì)非常靈活,肆意揮灑。
#與##(串化與連接)
C語(yǔ)言中的#與##可能很多人都不了解,更沒(méi)有用過(guò),因?yàn)樵谝话愕慕滩纳隙紱](méi)有對(duì)它們的介紹。但是把它們用好了,也能使我們的代碼別有一番格調(diào)。
串化,在宏定義中#可以將宏參數(shù)轉(zhuǎn)換為字符串,即在宏參數(shù)的開(kāi)頭和末尾添加引號(hào)。似乎有些雞肋,但是如果看到別人的代碼有用到串化的時(shí)候,我們需要能夠看懂。
再來(lái)看一下連接符##,它用來(lái)將參數(shù)和其它的內(nèi)容連接起來(lái),如下例:
#define CON1(a, b) a##e##b#define CON2(a, b) a##b##00
printf("%f\n", CON1(8.5, 2));printf("%d\n", CON2(12, 34));
printf("%f\n", 8.5e2); //展開(kāi)后的效果
printf("%d\n", 123400); //展開(kāi)后的效果
我在很多ARM官方評(píng)估板的配套代碼中看到過(guò)大量串化與連接的應(yīng)用,當(dāng)時(shí)我并不知道C語(yǔ)言還有串化連接這些東西(雖然我已經(jīng)用C語(yǔ)言有十幾年了),所以有些看不明白。通過(guò)百度學(xué)習(xí)了一下#與##,這才懂了。所以,C語(yǔ)言學(xué)得多精都不為過(guò),很多知識(shí)我們可能一輩子都不會(huì)用到,但是不代表我們可以不知道,因?yàn)閯e人在用。
OK,關(guān)于C語(yǔ)言方面的一些常見(jiàn)問(wèn)題、非常規(guī)操作以及認(rèn)知誤區(qū)振南就講這么多。C語(yǔ)言其實(shí)是博大精深,還是那句話:“學(xué)得多精都不為過(guò)!”我一直把嵌入式工程師比喻成“能與硬件對(duì)話的靈媒”,我們所使用的語(yǔ)言就是C語(yǔ)言。我們自認(rèn)為對(duì)C語(yǔ)言已經(jīng)足夠了解了,足夠精通了,但是我們又會(huì)發(fā)現(xiàn)在實(shí)際開(kāi)發(fā)過(guò)程中,會(huì)遇到很多新的問(wèn)題,很多問(wèn)題是與C語(yǔ)言本身相關(guān)的。
所以記?。骸皩W(xué)海無(wú)涯!” 有C語(yǔ)言方面的問(wèn)題,歡迎與振南來(lái)溝通交流,我自己也在不斷學(xué)習(xí)的過(guò)程中。





