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