問題引入
在C中,函數先定義,後使用。舉個簡單的例子
/************************* add by oscar999************************/func1(){ printf("this is func1!\n");}void main(){ func1();}
定義了一個簡單的函數func1, 調用的時候只需要"函數名()" 的方式就可以調用的到。(至於調用的過程是如何處理的,就要參考彙編的知識了。)
但是,在實際的開發過程中可能會遇到這種情況, 函數名事先並不確定,函數名是通過一個字串變數儲存的,這種狀況該如何調用呢?
更具體一點的例子,函數名是通過外部輸入進去了。
/************************* add by oscar999************************/void func1(){ printf("this is func1!\n");}void main(){ char c[20] = "\0"; printf("please input func name:"); scanf("%s",c); //input func1 //how run func1 ???}
該如何執行func1呢?
函數指標
解決以上問題之前, 首先引入函數指標的概念。
在C語言中,某一資料變數的記憶體位址可以儲存在相應的指標變數中,比如 int * , char * 等,
對於函數來說,也同樣如此,函數的首地址也可以儲存在某個函數指標變數裡,通過這個函數指標變數我們就可以調用所指向的函數了。
如何定義函數指標變數? 很簡單。
對應到上面 func1 函數,可以定義如下的指標變數。
void (*funcP)()
funcP這個名字可以隨便取。以下例子通過函數指標調用函數。
/************************* add by oscar999************************/func1(){ printf("this is func1!\n");}void main(){ void (*funcP)(); funcP = &func1; (*funcP)();}
使用函數指標實現函數名字串調用函數
有了如上的例子,不難想到:
如果我們事先定義一些函數指標,通過傳入的函數名字串,得到相應的函數指標,就可以實現函數調用了。
/************************* add by oscar999************************/ #include <stdio.h>typedef void (*funcP)();void func1(){ printf("this is func1!\n");}void func2(){ printf("this is func2!\n");}funcP getFuncPointer(char* sfuncname){ if(strcmp(sfuncname,"func1")==0) { return &func1; }else if(strcmp(sfuncname,"func2")==0){ return &func2; } return NULL; }void main(){ char c[20] = "\0"; funcP funcp = NULL; printf("please input func name:"); scanf("%s",c); //input func1 or func2 funcp = getFuncPointer(c); if(funcp!=NULL) { (*funcp)(); }}
你可能會想,通過傳入的string 直接調用對應的function不就可以了嗎?類似:
/************************* add by oscar999************************/ #include <stdio.h>typedef void (*funcP)();void func1(){ printf("this is func1!\n");}void func2(){ printf("this is func2!\n");}void main(){ char c[20] = "\0"; funcP funcp = NULL; printf("please input func name:"); scanf("%s",c); //input func1 or func2 if(strcmp(c,"func1")==0) { func1(); }else if(strcmp(c,"func2")==0){ func2(); }}
以上這種對於 function 較少的狀況可以使用, 但是func很多的話, 或者動態產生這部分的話,指標函數的方式就很好了。
實際設計師,可以把 函數名字串和函數指標放到一個name value set 中去, 這樣就可以很容易得到函數指標了。
帶參數的狀況