tft每日頭條

 > 生活

 > 回調函數的類型

回調函數的類型

生活 更新时间:2025-01-13 17:44:30

回調函數是利用函數指針做函數參數,實現的一種調用機制,具體任務的實現者,可以不知道什麼時候被調用。

回調機制原理:

當具體事件發生時,調用者通過函數指針調用具體函數。

回調機制的将調用者和被調函數分開,兩者互不依賴。

任務的實現和任務的調用可以實現松耦合(提前進行接口的封裝和設計)。

看以下實例:

#include <iostream> using namespace std; int add(int a, int b); void libfun(int (*pDis)(int a, int b)); int main(void) { int (*pfun)(int a, int b); pfun = add; libfun(pfun); return 0; } int add(int a, int b) { return a b; } int minus(int a, int b) { return a - b; } void libfun(int (*pDis)(int a, int b)) { int a, b; a = 1; b = 2; int c = add(a,b); //直接調用add函數 c = pDis(a, b); printf("%d", c); //通過函數指針做函數參數,間接調用add函數 //思考這樣寫pDis(a, b)有什麼好處? }

假設要實現減法呢?現在這幾個函數是在同一個文件當中,可以直接在

int libfun(int (*pDis)(int a, int b))

中修改,假設libfunc()是一個庫中的函數,你就隻能使用函數指針的回調機制了,通過函數指針參數将外部函數地址傳入來實現調用。

當然,函數 add()或minus() 的代碼作了修改,也不必改動庫的代碼,就可以正常實現調用。

最重要的是,即使将add換成另一個函數,也不需要修改libfun(),隻需在調用時将其函數指針參數使用不同的實參就行了。這就是低耦合的思想,便于程序的維護和升級。

再看一個例子:

#include <iostream> using namespace std; bool lesser(int a, int b); bool greater(int a, int b); void libSwap(bool (*pDis)(int a, int b)); // 通過函數直接來調用lesser()或greater()函數 void libSwap(); // 直接在函數體内調用lesser()或greater()函數 int main(void) { libSwap(lesser); //libSwap(greater); libSwap(); while(1); return 0; } bool greater(int a, int b) { return a > b; } bool lesser(int a, int b) { return a < b; } void libSwap(bool (*pDis)(int a, int b)) //通過函數指針做函數參數,間接調用add函數 { int a = 5, b = 7; if(pDis(a, b)) { int tmp = a; a = b; b = tmp; } cout<<a<<" "<<b<<endl; } void libSwap() //直接在函數體内調用lesser()或greater()函數 { int a = 5, b = 7; if(lesser(a,b)) //if(greater(a,b)) { int tmp = a; a = b; b = tmp; } cout<<a<<" "<<b<<endl; }

上列假設libSwap()是庫函數。庫使用者在main()中調用

void libSwap(bool (*pDis)(int a, int b))

此函數有一個函數指針,需要提供函數供其使用,此時庫使用者編寫greater()、lesser(),這兩個函數庫使用者并不直接調用,而是由libSwap()去調用。greater()、lesser()這種函數就稱為回調函數,整個設計機制就是回調函數調用機制。

所謂回調,就是客戶程序C調用服務程序S中的某個函數s(),然後S又在某個時候反過來調用C中的某個函數c(),對于C來說,這個c()便叫做回調函數。例如Win32下的窗口過程函數就是一個典型的回調函數。

一般說來,C不會自己調用c(),c()提供c()的目的就是讓S來調用它,而且是C不得不提供。由于S并不知道C提供的c()叫甚名誰,所以S會約定c()的接口規範(函數原型),然後由C提前通過S的一個函數r()告訴S自己将要使用c()函數,這個過程稱為回調函數的注冊,R稱為注冊函數。

在框架中,定義函數指針,相當于提前指定了一套協議接口。

對于排序函數,如果想用同一個排序函數來實現升序或降序排列,調用時不修改此函數的排序邏輯,可以考慮使用函數指針來調用回調函數,而stdlib.h庫中的qsort()函數即是如此來實現這一邏輯的:

#include <stdio.h> #include <stdlib.h> int compare(int a, int b) // 用于bubbleSort()的回調函數 { return a-b; //return b-a; } int cmp(const void* a, const void* b) // 用于庫函數qsort() { return (*((int*)a) - *((int*)b)); //return (*((int*)b) - *((int*)a)); } void bubbleSort(int arr[], int n, int (*compare)(int,int)) { // 隻需更改函數指針指向的回調函數,即可實現升序或降序排列 for(int i=0; i<n; i ) for(int j=0;j<n-i-1; j ) if(compare(arr[j],arr[j 1])>0) { int tmp = arr[j]; arr[j] = arr[j 1]; arr[j 1] = tmp; } } void arrOutput(int arr[], int n) { for(int i=0;i<n; i ) printf("%d ",arr[i]); printf("\n"); } int main() { int arr[] = {3,2,1,5,4}; int n = sizeof(arr)/sizeof(arr[0]); bubbleSort(arr,n,compare); arrOutput(arr,n); int arr2[] = {3,2,1,5,4}; qsort(arr2,n,sizeof(int),cmp); arrOutput(arr2,n); while(1); return 0; } /* 1 2 3 4 5 1 2 3 4 5 */

回調函數的類型(理解回調函數回調機制原理)1

-End-

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved