在c語言中,函數名也是指針變量git
函數名是指向函數的指針,當你建立一個叫test的函數的同時,也會建立一個test指針變量,變量中保存了函數的地址。該變量位於常量段。github
如何建立函數指針?
數組
假設咱們有一個函數叫go_to_warp_speed,函數的定義是這樣的。函數
int go_to_warp_speed(int speed){}ui
那麼要建立指向它的函數指針則應該:指針
int (*warp_fn)(int); warp_fn=go_to_warp_speed; warp_fn(4);//至關於go_to_warp_speed(4)
建立函數指針時,須要把函數的返回值類型和接收參數類型告訴c編譯器。code
例程:字符串
尋找Mr.Right.如下是保存男生數據的字符串數組:get
char *ADS[] = { "William: SBM GSOH likes sports, TV, dining", "Matt: SWM NS likes art, movies, theater", "Luis: SLM ND likes books, theater, art", "Mike: DWM DS likes trucks, sports and bieber", "Peter: SAM likes chess, working out and art", "Josh: SJM likes sports, movies and theater", "Jed: DBM likes theater, books and dining" };
而後是查詢條件,4個不一樣的函數,接收一樣的參數類型,可是判斷邏輯不一樣。編譯器
int sports_no_bieber(char *s) { return strstr(s, "sports") && !strstr(s, "bieber"); } int sports_or_workout(char *s) { return strstr(s, "sports") || strstr(s, "working out"); } int ns_theater(char *s) { return strstr(s, "NS") && strstr(s, "theater"); } int arts_theater_or_dining(char *s) { return strstr(s, "arts") || strstr(s, "theater") || strstr(s, "dining"); }
查找函數,參數爲一個函數指針int (*match)(char*)
void find(int (*match)(char *)) { int i; puts("Search results:"); puts("----------------"); for(i=0;i<NUM_ADS;i++){ if(match(ADS[i])) printf("%s\n",ADS[i]); } puts("----------------"); }
會使用形參做爲函數名直接傳參進去,還記得嗎,函數名是指向函數的指針。
主函數:
int main(){ find(sports_no_bieber); find(sports_or_workout); find(ns_theater); find(arts_theater_or_dining); return 0; }
在傳參的時候,直接將函數名傳入,沒有任何修飾。
要點:
函數名是指針。
函數指針的聲明要加括號,目的是保證*右結合,不肯定符號優先級的狀況下,加括號準沒錯。
給函數指針賦值之後,函數指針能夠像函數自己同樣接收參數,由於函數名的本質也是指針,它們指向同一個函數。
函數指針做爲參數時,將函數名直接傳入。
幾個概念要區分開,函數,函數名,函數指針。函數是執行運算的本體,函數名是指向函數的指針,函數指針能夠用聲明類型的函數賦值。
在函數指針的調用,賦值等運算中,本質上傳遞的是函數的地址(我的理解),調用函數指針時,能夠加*,給函數指針賦值時,能夠用&函數名,來獲取函數的地址,能夠不寫,便於閱讀,c編譯器能夠識別。