首頁>技術>

大家好,我是ZhengN。本次給大家分享一些C語言、嵌入式專案中的常用知識。

1、使用宏給結構體初始化

如果頻繁使用一個結構體的話,使用使用宏來給結構體進行賦值是很方便的一種做法。

例子:
#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;}
編譯、執行結果:

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

2、結構體內建函式指標

我們常常構造一些結構體來儲存資料,然後在一些函式中使用這些結構體。下次不妨把資料與操作資料的函式綁在一起,更清晰明瞭。

例子:
#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;}
編譯、執行結果:
void *malloc(size_t size) ;void *memcpy(void *destin, void *source, unsigned n);......

void *常常用於函式地封裝比較多,當然也有用在其它地方,比如在結構體內定義void*型別的私有指標方便擴充套件結構體。我們平時在封裝自己的函式時,也可以多考慮看看有沒有必要使用void*使得函式地通用性更強一些。

一般函式呼叫的順序都是上層函式(呼叫者)呼叫下層函式(被呼叫者)。而透過上圖我們可以看到下層模組的函式2呼叫了上層模組的函式3,這個呼叫過程與一般的呼叫過程相反,這個過程叫做回撥,這裡上層模組的函式3就是回撥函式。回撥函式的表現形式是函式指標。

C庫stdlib.h中帶有一個排序函式:qsort函式。這個排序函式的原型為:

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));

引數:

base-- 指向要排序的陣列的第一個元素的指標。nitems-- 由 base 指向的陣列中元素的個數。size-- 陣列中每個元素的大小,以位元組為單位。compar-- 用來比較兩個元素的函式,即函式指標(回撥函式)。
int compar(const void *p1, const void *p2);

如果compar返回值小於0(< 0),那麼p1所指向元素會被排在p2所指向元素的左面;

如果compar返回值等於0(= 0),那麼p1所指向元素與p2所指向元素的順序不確定;

如果compar返回值大於0(> 0),那麼p1所指向元素會被排在p2所指向元素的右面。

例子:

15
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 微服務過載保護原理與實戰