什麼是回調函數?
諸葛亮給趙子龍一個錦囊,吩咐他危急時打開按錦囊指示辦, 錦囊裏的命令就是“回調函數”,危急時刻就是“回調的時機”。
不同的錦囊裏可以有不同的命令。
我們繞點遠路來回答這個問題。
編程分爲兩類:系統編程(system programming)和應用編程(application programming)。所謂系統編程,簡單來說,就是編寫庫;而應用編程就是利用寫好的各種庫來編寫具某種功用的程序,也就是應用。系統程序員會給自己寫的庫留下一些接口,即API(application programming interface,應用編程接口),以供應用程序員使用。所以在抽象層的圖示裏,庫位於應用的底下。當程序跑起來時,一般情況下,應用程序(application program)會時常通過API調用庫裏所預先備好的函數。但是有些庫函數(library function)卻要求應用先傳給它一個函數,好在合適的時候調用,以完成目標任務。這個被傳入的、後又被調用的函數就稱爲回調函數(callback function)。
打個比方,有一家旅館提供叫醒服務,但是要求旅客自己決定叫醒的方法。可以是打客房電話,也可以是派服務員去敲門,睡得死怕耽誤事的,還可以要求往自己頭上澆盆水。這裏,“叫醒”這個行爲是旅館提供的,相當於庫函數,但是叫醒的方式是由旅客決定並告訴旅館的,也就是回調函數。而旅客告訴旅館怎麼叫醒自己的動作,也就是把回調函數傳入庫函數的動作,稱爲登記回調函數
#include<stdio.h>
// 方法指針的格式爲:int (*ptr)(char *p) 即:返回值(指針名)(參數列表)
typedef int (*CallBackFun)(char *p); // 爲回調函數命名,類型命名爲 CallBackFun,參數爲char *p
// 方法 Afun,格式符合 CallBackFun 的格式,因此可以看作是一個 CallBackFun
int Afun(char *p)
{
printf("Afun The callback to print out the characters %s!\n", p);
return 0;
}
// 方法 Bfun,格式符合 CallBackFun 的格式,因此可以看作是一個 CallBackFun
int Cfun(char *p)
{
printf("Cfun callback print:%s, Nice to meet you!\n", p);
return 0;
}
// 執行回調函數,方式一:通過命名方式
int call(CallBackFun pCallBack, char *p)
{
printf("call Print out the character directly %s!\n", p);
pCallBack(p);
return 0;
}
// int call2(char *p, int (*ptr)(char *p))
// 執行回調函數,方式二:直接通過方法指針
int call2(char *p, int (*ptr)())
{
printf("==============\n", p);
(*ptr)(p);
}
// 執行回調函數,方式一:通過命名方式
int call3(char *p, CallBackFun pCallBack)
{
printf("--------------\n", p);
pCallBack(p);
}
int main()
{
char *p = "hello";
call(Afun, p);
call(Cfun, p);
call2(p, Afun);
call2(p, Cfun);
call3(p, Afun);
call3(p, Cfun);
// int i = getchar();
// printf("Input: %c \n", i);
return 0;
}