C語(yǔ)言、嵌入式項(xiàng)目中一些常用知識(shí)及技巧:第一彈
大家好,我是ZhengN
。本次給大家分享一些C語(yǔ)言、嵌入式項(xiàng)目中的常用知識(shí)。
1、使用宏給結(jié)構(gòu)體初始化
如果頻繁使用一個(gè)結(jié)構(gòu)體的話,使用使用宏來(lái)給結(jié)構(gòu)體進(jìn)行賦值是很方便的一種做法。
例子:
左右滑動(dòng)查看全部代碼>>>
#include <stdio.h>
#define NEW_RECT(length, width) {(length), (width)}
typedef struct _Rect
{
int length;
int width;
}Rect;
int main(void)
{
Rect rect = NEW_RECT(10, 5);
printf("rect length = %d, width = %d\n", rect.length, rect.width);
return 0;
}
編譯、運(yùn)行結(jié)果:
這種方法在RT-Thread的底層gpio驅(qū)動(dòng)中也有見(jiàn)到:
2、結(jié)構(gòu)體內(nèi)置函數(shù)指針
我們常常構(gòu)造一些結(jié)構(gòu)體來(lái)存儲(chǔ)數(shù)據(jù),然后在一些函數(shù)中使用這些結(jié)構(gòu)體。下次不妨把數(shù)據(jù)與操作數(shù)據(jù)的函數(shù)綁在一起,更清晰明了。
例子:
左右滑動(dòng)查看全部代碼>>>
#include <stdio.h>
#define NEW_RECT(length, width) {(calc_area), (length), (width)}
typedef struct _Rect
{
int (*calc_area)(struct _Rect *pThis);
int length;
int width;
}Rect;
int calc_area(struct _Rect *pThis)
{
return (pThis->length * pThis->width);
}
int main(void)
{
Rect rect = NEW_RECT(10, 5);
printf("rect length = %d, width = %d\n", rect.length, rect.width);
printf("rect area = %d\n", rect.calc_area(&rect));
return 0;
}
編譯、運(yùn)行結(jié)果:
3、void*
之前在C語(yǔ)言對(duì)象編程第一彈:封裝與抽象中有用過(guò)void*
,。void*
其實(shí)我們平時(shí)都有接觸過(guò),比如:
左右滑動(dòng)查看全部代碼>>>
void *malloc(size_t size) ;
void *memcpy(void *destin, void *source, unsigned n);
......
void *
常常用于函數(shù)地封裝比較多,當(dāng)然也有用在其它地方,比如在結(jié)構(gòu)體內(nèi)定義void*
類型的私有指針?lè)奖銛U(kuò)展結(jié)構(gòu)體。
我們平時(shí)在封裝自己的函數(shù)時(shí),也可以多考慮看看有沒(méi)有必要使用void*
使得函數(shù)地通用性更強(qiáng)一些。推薦文章:【C進(jìn)階】同事用void把我給秀翻了!
4、動(dòng)態(tài)綁定、回調(diào)函數(shù)
回調(diào)函數(shù)可以達(dá)到動(dòng)態(tài)綁定的作用,在一定程度上可以降低層與層之間的耦合。關(guān)于回調(diào)函數(shù),之前已經(jīng)有寫(xiě)過(guò)一篇:C語(yǔ)言、嵌入式重點(diǎn)知識(shí):回調(diào)函數(shù)。但有很多初學(xué)的小伙伴可能還不理解回調(diào)函數(shù),可以借助下圖來(lái)理解:
一般函數(shù)調(diào)用的順序都是上層函數(shù)(調(diào)用者)調(diào)用下層函數(shù)(被調(diào)用者)。
而通過(guò)上圖我們可以看到下層模塊的函數(shù)2調(diào)用了上層模塊的函數(shù)3,這個(gè)調(diào)用過(guò)程與一般的調(diào)用過(guò)程相反,這個(gè)過(guò)程叫做回調(diào),這里上層模塊的函數(shù)3就是回調(diào)函數(shù)。回調(diào)函數(shù)的表現(xiàn)形式是函數(shù)指針。
C庫(kù)stdlib.h中帶有一個(gè)排序函數(shù):qsort函數(shù)。這個(gè)排序函數(shù)的原型為:
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));
參數(shù):
-
base-- 指向要排序的數(shù)組的第一個(gè)元素的指針。 -
nitems-- 由 base 指向的數(shù)組中元素的個(gè)數(shù)。 -
size-- 數(shù)組中每個(gè)元素的大小,以字節(jié)為單位。 -
compar-- 用來(lái)比較兩個(gè)元素的函數(shù),即函數(shù)指針(回調(diào)函數(shù))。
int compar(const void *p1, const void *p2);
如果compar返回值小于0(< 0),那么p1所指向元素會(huì)被排在p2所指向元素的左面;
如果compar返回值等于0(= 0),那么p1所指向元素與p2所指向元素的順序不確定;
如果compar返回值大于0(> 0),那么p1所指向元素會(huì)被排在p2所指向元素的右面。
例子:
左右滑動(dòng)查看全部代碼>>>
#include <stdio.h>
#include <stdlib.h>
int compar_int(const void *p1, const void *p2)
{
return (*((int*)p1) - *((int*)p2));
}
void test_qsort(void)
{
int arr[5] = {8, 5, 10, 1, 100};
printf("排序前:");
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
qsort((int*)arr, 5, 4, compar_int);
printf("\n排序后:");
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
}
int main(void)
{
test_qsort();
return 0;
}
編譯、運(yùn)行結(jié)果:
以上就是本次的分享,如有錯(cuò)誤,歡迎指出,謝謝。
這是第一彈,后續(xù)還會(huì)繼續(xù)分享更多實(shí)際開(kāi)發(fā)中實(shí)用的編程小技巧及編程經(jīng)驗(yàn),歡迎持續(xù)關(guān)注。本文只是盤(pán)點(diǎn)了一些實(shí)用小技巧,并不是說(shuō)無(wú)論什么場(chǎng)景下都要這么用,別濫用,還需具體問(wèn)題具體分析。
猜你喜歡
《這種求結(jié)構(gòu)體成員大小的方法你可能還沒(méi)掌握》
《Linux下能編譯成功,而Windows下編譯不過(guò)?》
為了便于公眾號(hào)讀者交流學(xué)習(xí),ZhengN創(chuàng)建了相關(guān)相關(guān)交流群??游挥邢?,感興趣的朋友可以掃碼下方二維碼加我微信,由我邀請(qǐng)入群:
歡迎大家進(jìn)群交流、共同進(jìn)步。同時(shí),我也會(huì)關(guān)注一些大家問(wèn)的一些問(wèn)題,從中挑選一些具有代表性的、并且在我知識(shí)范圍內(nèi)的問(wèn)題寫(xiě)出相關(guān)文章做分享。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!