大家好,我是雜燴君
。本次給大家分享幾個嵌入式C中的實用技巧。
1、動態(tài)綁定、回調(diào)函數(shù)
回調(diào)函數(shù)可以達到動態(tài)綁定的作用,在一定程度上可以降低層與層之間的耦合。關于回調(diào)函數(shù),之前已經(jīng)有寫過一篇:C語言、嵌入式重點知識:回調(diào)函數(shù)。可能很多初學的小伙伴可能還不理解回調(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;
}
編譯、運行結果:

以上就是本次的分享,如有錯誤,歡迎指出,謝謝。這是第一彈,后續(xù)還會繼續(xù)分享更多實際開發(fā)中實用的編程小技巧及編程經(jīng)驗。歡迎持續(xù)關注。本文只是盤點了一些實用小技巧,并不是說無論什么場景下都要這么用,還需具體問題具體分析。
2、使用宏給結構體初始化
如果頻繁使用一個結構體的話,使用使用宏來給結構體進行賦值是很方便的一種做法。
例子:
#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;
}
編譯、運行結果:

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

3、結構體內(nèi)置函數(shù)指針
我們常常構造一些結構體來存儲數(shù)據(jù),然后在一些函數(shù)中使用這些結構體。下次不妨把數(shù)據(jù)與操作數(shù)據(jù)的函數(shù)綁在一起,更清晰明了。
相關文章:什么是不完全類型?
例子:
#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;
}
編譯、運行結果:

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

嵌入式C語言知識總結

嵌入式C語言的結構特點

評論