1. 程式人生 > 程式設計 >關於c語言中回撥函式的理解

關於c語言中回撥函式的理解

前言

在計算機程式設計中,回撥函式,或簡稱回撥,是指通過函式引數傳遞到其它程式碼的,某一塊可執行程式碼的引用。這一設計允許了底層程式碼呼叫在高層定義的子程式。
這段話不是那麼好理解,不同語言實現回撥的方式有些許不同。其實可以這樣理解,回撥就是在一個函式中呼叫另外一個函式。

關於c語言中回撥函式的理解

在c語言中,回撥是使用函式指標來實現的。 函式指標——顧名思義,是指向一個函式的指標。通常函式指標有兩個方面的用途,一個是轉換表(jump table),另一個是作為引數傳遞給一個函式。
下面是兩個函式指標的宣告

int(*f)(int,float);int*(*g[])(int,float);

前者把f宣告為一個函式指標,它所指的函式接受兩個引數,分別是一個整型值和浮點型值,並返回一個整型值。

後者把g宣告為一個數組,陣列的元素型別是一個函式指標,它所指向的函式接受兩個引數,分別是一個整型值和浮點型值,並返回一個整型指標。

關於c語言中回撥函式的理解

需要注意的是,簡單宣告一個函式指標並不意味著它馬上就可以使用。和其他指標一樣,對函式指標執行間接訪問之前必須把它初始化為指向某個函式。下面的程式碼段說明了一種初始化函式指標的方法。

intf(int);int(*pf)(int) = f;

第 2 個宣告建立了函式指標pf,並把它初始化為指向函式f。函式指標的初始化也可以通過一條賦值語句來完成。在函式指標的初始化之前具有f的原型是很重要的,否則編譯器就無法檢查f的型別是否與pf所指向的型別一致。

通過一個例子簡單介紹回撥函式的使用

大家應該都對c語言的庫函式qsort有所瞭解,qsort宣告如下

void qsort(void*base,size_tnitems,size_tsize,int(*compar)(constvoid*,constvoid*))

可以看到,它的第三個引數是一個函式指標,傳入兩個沒有定義指標指向的型別的引數a,b,返回一個整型值。實際上這裡使用了回撥函式。通過回撥函式,qsort可以在執行時呼叫使用者定義的函式(底層程式碼呼叫在高層定義的子程式)。
這裡我們設計一個簡單的sort函式,來理解回撥過程

1、定義函式指標

typedefint(*compar)(constint*a,constint*b);

2、自定義sort函式,為了簡單,這裡使用氣泡排序

int*sort(int*nums,intn,compar cmp){int*target =malloc(n*sizeof(int));if(!target) perror("Memory error");memcpy(target,num,n *sizeof(int));for(inti =0; i < n; i++) {for(intj = i+1; j < n; j++) {if(cmp(target[i],target[j]) >0) {target[i] ^= target[j] ^= target[i] ^= target[j];}}}returntarget;}

3、實現函式回撥

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<errno.h>typedefint(*compar)(constint*a,constint*b);// 定義實現回撥函式的"呼叫函式"int*sort(int*nums,target[j]) <=0) {target[i] ^= target[j] ^= target[i] ^= target[j];}}}returntarget;}
// 定義回撥函式intcmp1(inta,intb){returna < b;}intmain(intargc,charconst*argv[]){inta[10] = {1,4,3,1,10,5};int*x = bubble_sort(a,7,cmp1);for(inti =0; i <7; i++)printf("%d ",x[i]);printf("\n");return0;}

執行結果:

1
1 1 3 4 4 5 10

呼叫函式向其函式中傳遞int (*compar)(const int *a,const int *b);這是int cmp1(int a,int b)函式的入口地址,即PC指標可以通過移動到該地址執行int cmp1(int a,int b)函式,可以通過類比陣列來理解。

實現函式呼叫中,函式呼叫了“呼叫函式”,再在其中進一步呼叫被“呼叫函式”。相比於主函式直接呼叫“被調函式”,這種方法為使用者,而不是開發者提供了靈活的介面。另外,函式入口可以像變數一樣設定同樣為開發者提供了靈活性。

總結

到此這篇關於c語言中回撥函式理解的文章就介紹到這了,更多相關c語言中回撥函式理解內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!