int *f();
f爲一個函數,返回值類型是一個指向整形的指針。node
int (*f)();
兩對括號,第二對括號是函數調用操做符,但第一對括號只起到聚組的做用。數組
f爲一個函數指針,它所指向的函數返回一個整型值。函數
int *(*f)();
f是一個函數指針,指向的函數返回值是一個整形指針。spa
int *f[]
下標的優先級更高,因此f是一個數組,元素類型是指向整形的指針。指針
int (*f[]) ();
這裏有兩對括號,第一對括號的表達式*f[]首先進行求值。f是一個元素爲某種類型的指針的數組。第二對括號是函數調用操做符。總結:f是一個數組,數組元素的類型是函數指針,它所指向的函數的返回值是一個整型值。code
int (*f)(int,float); int *(*g[])(int,float);
第一個,f是一個函數指針,所指向的函數接受兩個參數。並返回一個整形。blog
第二個,g位一個數組,數組的元素類型是一個函數指針。它所指向的函數接受兩個參數,並返回一個整形指針。內存
函數指針原型
注意:簡單聲明一個函數指針並不意味着它立刻就能夠使用。對函數指針執行間接訪問以前必須把它初始化爲指向某個函數。編譯器
int f(int); int (*pf)(int) = &f;
注意:初始化表達式中的&操做符是可選的,由於函數名被使用時老是由編譯器把它轉換爲函數指針。&操做符只是顯式地說明了編譯器將隱式執行的任務。
int ans; ans = f(25); ans = (*pf)(25); ans = pf(25);
第一條語句使用名字調用函數f,但它的執行過程當中可能和你想象的不太同樣。函數名f首先被轉換爲一個函數指針,該指針指定函數在內存中的位置。
第二條語句:對pf執行間接訪問操做,它把函數指針轉換爲一個函數名。
第三條語句和前面兩條語句的效果是同樣的。間接訪問操做並不是必需,由於編譯器須要的是一個函數指針
函數指針的應用舉例:
Node * search_list(Node *node,void const *value,int (*compare)(void const *,void const *)) { while(node != NULL) { if(compare(&node->value,value) == 0) break; node = node->link; } return node; } int compare_ints(void const *a,void const *b) { if(*(int *)a == *(int *)b) return 0; else return 1; }
上面函數使用:
desired_node = search_list(root,&desired_value,compare_ints);
函數指針數組:聲明並初始化一個函數指針數組。惟一需留心之處就是確保這些函數的原型出如今這個數組的聲明以前。
double add(double,double); double sub(double,double); double mul(double,double); double div(double,double); double (*oper_func[])(double,double) = { add,sub,mul,div,... };
初始化列表中各個函數名的正確順序取決於程序中用於表示每一個操做符的整形代碼。這個例子中ADD是0,SUB是1,MUL是2.
調用操做
result = oper_func[oper](op1,op2);