函數指針:是一個指針,指向函數入口地址的指針。本質就是一個數據類型,能夠來定義變量。框架
函數指針正向調用:在應用程序中直接給函數指針賦值,調用指針指向的函數,就是正向調用。
函數指針反向調用(回調函數):在應用程序中函數指針做爲函數參數,在函數裏面調用指針所指向的函數,就是回調函數。ide
一、調用者不須要關心被調用者是如何實現的,只須要在特定的時機,選擇傳入某個函數地址;
二、被調用者不須要關心本身何時被調用,只須要實現本身的功能就好。函數
一天,劉備須要南下找孫權商量聯合抗曹的事情,但是擔憂本身可能有去無回了,可是軍師諸葛亮有必須在家裏處理家務事。因此最近非常頭疼。spa
諸葛亮看在眼裏,爲了打消主公的擔心,在家裏製做了三個錦囊,這三個錦囊能夠幫助劉備化險爲夷,可是必須在遇到困難時,按照順序打開才行。指針
諸葛亮就錦囊交給劉備,而且告訴了他在遇到一個困難時,按照順序打開一個錦囊就可化險爲夷。劉備因而就放心的南下了,最後成功的聯合了孫權一塊兒抵抗曹軍。code
這個故事告訴咱們:接口
一、諸葛亮不須要知道劉備何時會遇到困難,只須要知道他在有困難時怎麼幫助他就行了(三個錦囊)ip
二、劉備並不知道錦囊裏是什麼,只須要本身在遇到困難時,打開錦囊就行了回調函數
三、三個錦囊就是實現功能的函數,而劉備就是經過打開錦囊這個函數來回調錦囊裏的功能函數的。io
下面經過代碼來演示函數指針的正向調用和逆向調用(回調函數)
正向調用代碼(C語言)
#include <stdio.h> /*定義一個函數指針的數據類型*/ typedef double (*Calc)(double num1,double num2); /*定義實現加減乘除運算的函數*/ double Add(double num1,double num2) { return num1+num2; } double Subtract (double num1,double num2) { return num1-num2; } double Multiply (double num1,double num2) { return num1*num2; } double Divide(double num1,double num2) { return num1/num2; } int main(int argc, char *argv[]) { /*定義一個函數指針類型的變量*/ Calc ca; /*函數指針的正向調用*/ double num1 = 3.3; double num2 = 1.1; ca = Add; printf("num1 + num2 = %lf\n",ca(num1,num2)); ca = Subtract; printf("num1 - num2 = %lf\n",ca(num1,num2)); ca = Multiply; printf("num1 * num2 = %lf\n",ca(num1,num2)); ca = Divide; printf("num1 / num2 = %lf\n",ca(num1,num2)); return 0; }
函數指針的逆向調用代碼(回調函數)
#include <stdio.h> /*定義一個函數指針的數據類型*/ typedef double (*Calc)(double num1,double num2); /*定義實現加減乘除運算的函數 ==> 能夠封裝到一個.c文件中 ==> 也能夠封裝成動態庫DLL 供調用*/ double Add(double num1,double num2) { return num1+num2; } double Subtract (double num1,double num2) { return num1-num2; } double Multiply (double num1,double num2) { return num1*num2; } double Divide(double num1,double num2) { return num1/num2; } /*將函數指針做爲此函數參數,經過此函數來回調指針所指向的函數 ==> 能夠是一個通用的接口供應用程序來調用 ==> 也能夠是一個框架供應用程序來調用*/ void CommCalc(double num1,double num2,Calc func) { printf("num1 calc num2 = %lf\n",func(num1,num2)); } int main(int argc, char *argv[]) { /*定義一個函數指針類型的變量*/ Calc ca; /*函數指針的正向調用*/ double num1 = 3.3; double num2 = 1.1; CommCalc(num1,num2,Add); CommCalc(num1,num2,Subtract); CommCalc(num1,num2,Multiply); CommCalc(num1,num2,Divide); return 0; }
經過函數指針的正向調用逆向調用代碼的比較,你們應該能夠看出回調函數的意義了吧,咱們能夠把調用回調函數的函數寫在一個框架中,當咱們須要使用回調函數時,不須要動框架代碼,只須要調用框架中的函數來完成就能夠了。
沙米水平有限,但願你們多多指導,一塊兒探討,一塊兒提升。