日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 大橙子瘋嵌入式


1、前言

函數(shù)調(diào)用很好理解,即使剛學(xué)沒多久的朋友也知道函數(shù)調(diào)用是怎么實現(xiàn)的,即調(diào)用一個已經(jīng)封裝好的函數(shù),實現(xiàn)某個特定的功能。

把一個或者多個功能通過函數(shù)的方式封裝起來,對外只提供一個簡單的函數(shù)接口,然后在其他地方調(diào)用即可

2、函數(shù)調(diào)用方式

函數(shù)調(diào)用難道還能怎么調(diào)用?不就封裝好直接調(diào)用嗎???

函數(shù)調(diào)用方式分為兩種:直接調(diào)用間接調(diào)用

直接調(diào)用
直接調(diào)用就是我們平常使用的方式,下面的方式就屬于直接調(diào)用了。

int SumFun(int a, int b) { return a + b;
} int main() { // 直接調(diào)用定義好的函數(shù) int sum = SumFun(5, 6); printf("sum=%d", sum); return 0;
}

間接調(diào)用
間接調(diào)用在初學(xué)時很難使用到,這是通過函數(shù)指針的方式實現(xiàn)的。

函數(shù)指針本質(zhì)是一個指針變量,是一個指向函數(shù)的指針(函數(shù)本身也是有地址的,指向的是函數(shù)入口);
指針函數(shù)本質(zhì)是一個函數(shù),其返回值為指針。

函數(shù)指針的用法如下:

typedef int (*FunctionCB)(int, int); int SumFun(int a, int b) { return a + b;
} int main() { // 將定義好的函數(shù)賦值給函數(shù)指針 FunctionCB pfnSum = SumFun; // 通過函數(shù)指針間接調(diào)用 int sum = pfnSum(5, 6); printf("sum=%d", sum); return 0;
}

3、什么場景使用

函數(shù)指針在軟件架構(gòu)分層設(shè)計中十分重要,因為分層設(shè)計中有一個設(shè)計原則,那就是下層函數(shù)不能直接調(diào)用上層函數(shù),那么可以通過函數(shù)指針的方式實現(xiàn);一般稱上層通過函數(shù)指針賦值給下層的函數(shù)為回調(diào)函數(shù)。

什么情況會存在需要下層程序需要調(diào)用上層程序的呢?
比如串口數(shù)據(jù)接收,雖然可以通過查詢的方式接收,但是遠不及通過串口中斷的方式接收及時,當(dāng)接收完成時,需要立即通知上層讀取數(shù)據(jù)進行處理,而不是等待上層程序查詢讀取。

如何實現(xiàn)呢?
比如硬件抽象層/驅(qū)動層中的串口模塊實現(xiàn)函數(shù)

/************* UART.c 文件 ****************/ static UartRecvCB sg_pfnUartRecv; // 設(shè)置數(shù)據(jù)幀接收處理回調(diào)函數(shù) void UART_SetRecvCallback(UartRecvCB pfnUartRecv) {
 sg_pfnUartRecv = pfnUartRecv;
} void UART_Task(void) { if (RecvEnd)
 { // 數(shù)據(jù)一幀接收完成立即調(diào)用 if (sg_pfnUartRecv != NULL)
 {
 sg_pfnUartRecv(UartRecvBuf, UartRecvLength);
 }
 }
} /************* UART.h 文件 ****************/ typedef void (*UartRecvCB)(const char *, int); extern void UART_SetRecvCallback(UartRecvCB pfnUartRecv); extern void UART_Task(void);

應(yīng)用層代碼中實現(xiàn)回調(diào)函數(shù),并調(diào)用下層函數(shù)。

// 回調(diào)函數(shù):串口數(shù)據(jù)處理 void OnUartRecvProcess(const char *pBuf, int length) { // 處理串口數(shù)據(jù) printf("Recv: %s", pBuf);
} int main() {
 UART_SetRecvCallback(OnUartRecvProcess); while(1)
 { if (TimeFlag)
 {
 UART_Task();
 }
 }
}

上述示例中通過函數(shù)指針的方式間接調(diào)用了應(yīng)用層的函數(shù),而且并不違背分層設(shè)計原則。
如果看代碼不能立即理解的話,可以嘗試通過下圖理解:

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉