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);