大家好,我是雜燴君
。本次給大家分享幾個嵌入式C中的實(shí)用技巧。
1、動態(tài)綁定、回調(diào)函數(shù)
回調(diào)函數(shù)可以達(dá)到動態(tài)綁定的作用,在一定程度上可以降低層與層之間的耦合。關(guān)于回調(diào)函數(shù),之前已經(jīng)有寫過一篇:C語言、嵌入式重點(diǎn)知識:回調(diào)函數(shù)。可能很多初學(xué)的小伙伴可能還不理解回調(diào)函數(shù),可以借助下圖來理解:

一般函數(shù)調(diào)用的順序都是上層函數(shù)(調(diào)用者)調(diào)用下層函數(shù)(被調(diào)用者)。而通過上圖我們可以看到下層模塊的函數(shù)2調(diào)用了上層模塊的函數(shù)3,這個調(diào)用過程與一般的調(diào)用過程相反,這個過程叫做回調(diào),這里上層模塊的函數(shù)3就是回調(diào)函數(shù)?;卣{(diào)函數(shù)的表現(xiàn)形式是函數(shù)指針。
C庫stdlib.h中帶有一個排序函數(shù):qsort函數(shù)。這個排序函數(shù)的原型為:
voidqsort(void*base,size_tnitems,size_tsize,int(*compar)(constvoid*,constvoid*));
參數(shù):
- base-- 指向要排序的數(shù)組的第一個元素的指針。
- nitems-- 由 base 指向的數(shù)組中元素的個數(shù)。
- size-- 數(shù)組中每個元素的大小,以字節(jié)為單位。
- compar-- 用來比較兩個元素的函數(shù),即函數(shù)指針(回調(diào)函數(shù))。
intcompar(constvoid*p1,constvoid*p2);
如果compar返回值小于0(< 0),那么p1所指向元素會被排在p2所指向元素的左面;
如果compar返回值等于0(= 0),那么p1所指向元素與p2所指向元素的順序不確定;
如果compar返回值大于0(> 0),那么p1所指向元素會被排在p2所指向元素的右面。
例子:

#include
#include
intcompar_int(constvoid*p1,constvoid*p2)
{
return(*((int*)p1)-*((int*)p2));
}
voidtest_qsort(void)
{
intarr[5]={8,5,10,1,100};
printf("排序前:");
for(inti=0;i5;i++)
{
printf("%d",arr[i]);
}
qsort((int*)arr,5,4,compar_int);
printf("
排序后:");
for(inti=0;i5;i++)
{
printf("%d",arr[i]);
}
}
intmain(void)
{
test_qsort();
return0;
}
編譯、運(yùn)行結(jié)果:

以上就是本次的分享,如有錯誤,歡迎指出,謝謝。這是第一彈,后續(xù)還會繼續(xù)分享更多實(shí)際開發(fā)中實(shí)用的編程小技巧及編程經(jīng)驗(yàn)。歡迎持續(xù)關(guān)注。本文只是盤點(diǎn)了一些實(shí)用小技巧,并不是說無論什么場景下都要這么用,還需具體問題具體分析。
2、使用宏給結(jié)構(gòu)體初始化
如果頻繁使用一個結(jié)構(gòu)體的話,使用使用宏來給結(jié)構(gòu)體進(jìn)行賦值是很方便的一種做法。
例子:
#include
#defineNEW_RECT(length,width){(length),(width)}
typedefstruct_Rect
{
intlength;
intwidth;
}Rect;
intmain(void)
{
Rectrect=NEW_RECT(10,5);
printf("rectlength=%d,width=%d
",rect.length,rect.width);
return0;
}
編譯、運(yùn)行結(jié)果:

這種方法在RT-Thread的底層gpio驅(qū)動中也有見到:

3、結(jié)構(gòu)體內(nèi)置函數(shù)指針
我們常常構(gòu)造一些結(jié)構(gòu)體來存儲數(shù)據(jù),然后在一些函數(shù)中使用這些結(jié)構(gòu)體。下次不妨把數(shù)據(jù)與操作數(shù)據(jù)的函數(shù)綁在一起,更清晰明了。
相關(guān)文章:什么是不完全類型?
例子:
#include
#defineNEW_RECT(length,width){(calc_area),(length),(width)}
typedefstruct_Rect
{
int(*calc_area)(struct_Rect*pThis);
intlength;
intwidth;
}Rect;
intcalc_area(struct_Rect*pThis)
{
return(pThis->length*pThis->width);
}
intmain(void)
{
Rectrect=NEW_RECT(10,5);
printf("rectlength=%d,width=%d
",rect.length,rect.width);
printf("rectarea=%d
",rect.calc_area(&rect));
return0;
}
編譯、運(yùn)行結(jié)果:

4、使用do{}while(0)封裝宏
#defineDBG_PRINTF(fmt,args...)
do
{
printf("<>" ,__FILE__,__LINE__,__FUNCTION__);
printf(fmt,##args);
}while(0)
具體說明可查閱往期文章:
5、void*
之前在C語言對象編程第一彈:封裝與抽象中有介紹過void*
。void*
其實(shí)我們平時都有接觸過,比如:
void*malloc(size_tsize);
void*memcpy(void*destin,void*source,unsignedn);
......
void *
常常用于函數(shù)地封裝比較多,當(dāng)然也有用在其它地方,比如在結(jié)構(gòu)體內(nèi)定義void*
類型的私有指針方便擴(kuò)展結(jié)構(gòu)體。我們平時在封裝自己的函數(shù)時,也可以多考慮看看有沒有必要使用void*
使得函數(shù)地通用性更強(qiáng)一些。
end
審核編輯 :李倩
-
嵌入式
+關(guān)注
關(guān)注
5152文章
19675瀏覽量
317655 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4381瀏覽量
64903
原文標(biāo)題:分享幾個嵌入式 C 中的實(shí)用技巧
文章出處:【微信號:yikoulinux,微信公眾號:一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
在嵌入式開發(fā)中,你是如何理解嵌入式C編程的?
分享幾個嵌入式學(xué)習(xí)的小技巧
嵌入式系統(tǒng)中的Python與C / C ++的相關(guān)資料分享
幾個硬件和嵌入式軟件的問題
嵌入式實(shí)時程序設(shè)計(jì)中C/C++代碼的優(yōu)化
嵌入式c語言編程(由淺入深)

嵌入式C的主要特點(diǎn)以及嵌入式C與標(biāo)準(zhǔn)C異同沖區(qū)重用
C和嵌入式

嵌入式C++編程

嵌入式C語言知識總結(jié)

嵌入式程序員應(yīng)知道的幾個基本問題

嵌入式C語言的結(jié)構(gòu)特點(diǎn)

評論