函數與指針

函數類型

數組是有類型的,一樣的,函數也有類型。函數的類型是由返回值類型參數類型以及參數個數三者共同決定的。數組

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

  1. 調用者不知道被調函數的具體內容是什麼
  2. 被調函數不知道本身什麼時候被調用
  3. 當具體事件發生時,調用者經過函數指針來調用被調函數
  4. 調用者與被調函數互不依賴

實例代碼

咱們在用餐時,根據喜愛不一樣,會選擇吃的食物也不一樣。有的人喜歡吃米食,有的人喜歡吃麪食...,那麼根據飲食習慣的不一樣,定義兩種食物,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()也不知道本身什麼時候會被調用,也可能不會被調用,視狀況而定。而且,調用者是經過函數指針完成對被調函數的調用,且調用者與被調函數徹底互不依存。所以,徹底符合回調機制的原理。

相關文章
相關標籤/搜索