C語言中的回撥函式



回撥函式用途廣泛,尤其是在事件驅動的程式設計中。當觸發特定事件時,對映到該事件的回撥函式將被執行以響應這些事件。這通常用於 GUI 應用程式中,例如按鈕點選可以啟動一系列預定義的動作。

回撥函式

回撥函式基本上是任何作為引數傳遞給其他程式碼的可執行程式碼,該程式碼預計會在給定時間回叫或執行該引數。我們可以用其他方式定義它,例如:如果函式的引用作為引數傳遞給另一個函式以進行呼叫,則稱為回撥函式。

回撥機制依賴於**函式指標**。函式指標是一個儲存函式記憶體地址的變數

這是一個簡單的 C 語言中的 hello() 函式:

void hello(){
   printf("Hello World.");
}

我們如下宣告指向此函式的指標:

void (*ptr)() = &hello;

現在我們可以使用此函式指標呼叫該函式,**(*ptr)();**

C語言中回撥函式的示例

在這個例子中,hello() 函式被定義為 myfunction() 的引數。

#include <stdio.h>

void hello(){
   printf("Hello World\n");
}

void callback(void (*ptr)()){

   printf("Calling a function with its pointer\n");
   
   (*ptr)();   // calling the callback function
}

main(){

   void (*ptr)() = hello;

   callback(ptr);
}

輸出

Calling a function with its pointer
Hello World

帶引數的回撥函式

在下面給出的示例中,我們還聲明瞭兩個具有相同原型的函式:square() 和 root()。

int square(int val){
   return val*val;
}

int root(int val){
   return pow(val, 0.5);
}

回撥函式被定義為接收一個引數以及一個具有整數引數的函式指標,該引數與上述函式匹配。

int callback(int a,  int (*ptr)(int)){

   int ret = (*ptr)(a);

   return ret;

}

在 main() 函式中,我們透過傳遞一個整數和函式名(**square** / **root**)來呼叫回撥,該函式名成為回撥定義中的函式指標。

帶引數的回撥函式示例

完整的程式碼如下:

#include <stdio.h>
#include <math.h>

int callback(int a, int (*print_callback)(int));
int square(int value);
int root (int value);

int main(){
   
   int x = 4;
   
   printf("Square of x: %d is %d\n", x, callback(x, square));
   printf("Square root of x: %d is %d\n", x, callback(x, root));
   
   return 0;
}

int callback(int a,  int (*ptr)(int)){
   int ret = (*ptr)(a);
   return ret;
}

int square(int val){
   return val*val;
}

int root(int val){
   return pow(val, 0.5);
}

輸出

Square of x: 4 is 16
Square root of x: 4 is 2

C語言中回撥函式的型別

有兩種**回撥函式型別**:

同步回撥

當回撥函式傳遞給另一個函式時,該函式將其作為其過程的一部分執行,則該回調函式是同步的。呼叫函式在繼續執行之前等待回撥函式完成。當您需要立即獲得結果或希望確保在繼續執行之前完成一項任務時,這很有用。

非同步回撥

在這種情況下,呼叫函式觸發回撥函式,但不等待它完成。相反,它繼續執行。它導致非阻塞操作。它通常用於事件驅動的程式設計中。

通用回撥函式幫助開發人員編寫用途廣泛且更具適應性的 C 程式。

在本章中,我們解釋瞭如何使用函式指標來增強 C 程式的靈活性。此外,我們展示瞭如何建立不限於特定函式指標型別的通用回撥函式。

廣告