數組是有類型的,一樣的,函數也有類型。函數的類型是由返回值類型,參數類型以及參數個數三者共同決定的。數組
type (parameter list)
C語言中,可使用typedef關鍵字對數組類型進行重命名,既然函數也是有類型的,那麼一樣可使用typedef爲函數類型進行重命名。例如,ide
typedef int F (int, int); typedef void P (char, int); typedef float pf (float, float, int); typedef char pc (void);
int型的數據能夠經過int 指針指向,float類型的數據可使用float 指針指向,數組類型能夠經過數組指針指向,那麼函數類型就能夠經過函數指針指向。函數
函數指針,本質是指針,用於指向一個函數。前面講過,一個函數,它的類型是由返回值類型,參數類型以及參數個數共同決定,所以,指針
int add(int, int); float minus(float, float); int (*pi) (int, int) = add; float (*pf) (float, float) = minus;
因爲typedef關鍵字能夠對函數類型重命名,所以,上面那種寫法又能夠簡寫爲,code
typedef int PI (int int); typedef float PF (float, float); PI* pi = add; PF* pf = minus;
typedef int (FUNC) (int); int test(int i){ return i + i; } void func(){ printf("Call func()...\n"); } int main(){ FUNC* pt = test; void (*pf) () = &func; //void (*pf) () = func; pf(); (*pf)(); //func(); }
因爲函數名就是函數入口地址,所以對函數名取地址,其實仍是函數入口地址自己,沒有什麼區別。所以,如下兩種寫法等價,事件
void (*pf) () = &func; 等價於 void (*pf) () = func;
一樣的是,調用函數時的寫法也是等價的,回調函數
pf(); 等價於 (*pf)(); 等價於 func();
回調函數是利用函數指針實現的一種回調機制。回調機制的基本原理:it
咱們在用餐時,根據喜愛不一樣,會選擇吃的食物也不一樣。有的人喜歡吃米食,有的人喜歡吃麪食...,那麼根據飲食習慣的不一樣,定義兩種食物,class
int Rice(void){ printf("I like eatting rice...\n"); return 3; } int Noddle(void){ printf("I like eatting noddle...\n"); return 2; }
這個時候,小明和小紅一塊兒用餐,小明喜歡吃米食,小紅喜歡吃麪食。因而就有,test
typedef int (*FOOD) (void); void Eat(FOOD food){ printf("begin to eat...\n"); int result = food(); printf("I eat %d bowls...\n", result); printf("end...\n"); } int main(){ Eat(Rice); //小明吃米食 Eat(Noddle); //小紅吃麪食 return 0; }
以上的狀況就是,Eat()做爲調用者,不知道本身調用的具體內容是什麼,多是Rice(),多是Noddle(),也多是其餘;而被調函數Rice(),Noddle()也不知道本身什麼時候會被調用,也可能不會被調用,視狀況而定。而且,調用者是經過函數指針完成對被調函數的調用,且調用者與被調函數徹底互不依存。所以,徹底符合回調機制的原理。