C 函式指標與回撥函式

函式指標

函式指標是指向函式的指標變數。

通常我們說的指標變數是指向一個整型、字元型或陣列等變數,而函式指標是指向函式。

函式指標可以像一般函式一樣,用於呼叫函式、傳遞引數。

函式指標變數的宣告:

typedef int (*fun_ptr)(int,int); // 宣告一個指向同樣引數、返回值的函式指標型別

例項

以下例項聲明瞭函式指標變數 p,指向函式 max:

例項

#include <stdio.h> int max(int x, int y) { return x > y ? x : y; } int main(void) { /* p 是函式指標 */ int (* p)(int, int) = & max; // &可以省略 int a, b, c, d; printf("請輸入三個數字:"); scanf("%d %d %d", & a, & b, & c); /* 與直接呼叫函式等價,d = max(max(a, b), c) */ d = p(p(a, b), c); printf("最大的數字是: %d\n", d); return 0; }

編譯執行,輸出結果如下:

請輸入三個數字:1 2 3
最大的數字是: 3

回撥函式

函式指標作為某個函式的引數

函式指標變數可以作為某個函式的引數來使用的,回撥函式就是一個通過函式指標呼叫的函式。

簡單講:回撥函式是由別人的函式執行時呼叫你實現的函式。

以下是來自知乎作者常溪玲的解說:

你到一個商店買東西,剛好你要的東西沒有貨,於是你在店員那裡留下了你的電話,過了幾天店裡有貨了,店員就打了你的電話,然後你接到電話後就到店裡去取了貨。在這個例子裡,你的電話號碼就叫回調函式,你把電話留給店員就叫登記回撥函式,店裡後來有貨了叫做觸發了回撥關聯的事件,店員給你打電話叫做呼叫回撥函式,你到店裡去取貨叫做響應回撥事件。

例項

例項中 populate_array 函式定義了三個引數,其中第三個引數是函式的指標,通過該函式來設定陣列的值。

例項中我們定義了回撥函式 getNextRandomValue,它返回一個隨機值,它作為一個函式指標傳遞給 populate_array 函式。

populate_array 將呼叫 10 次回撥函式,並將回撥函式的返回值賦值給陣列。

例項

#include <stdlib.h> #include <stdio.h> // 回撥函式 void populate_array(int *array, size_t arraySize, int (*getNextValue)(void)) { for (size_t i=0; i<arraySize; i++) array[i] = getNextValue(); } // 獲取隨機值 int getNextRandomValue(void) { return rand(); } int main(void) { int myarray[10]; /* getNextRandomValue 不能加括號,否則無法編譯,因為加上括號之後相當於傳入此引數時傳入了 int , 而不是函式指標*/ populate_array(myarray, 10, getNextRandomValue); for(int i = 0; i < 10; i++) { printf("%d ", myarray[i]); } printf("\n"); return 0; }

編譯執行,輸出結果如下:

16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709