函数指针
函数指针最常见的用途:转换表 和 作为参数传递给另一个函数。
简单声明一个函数指针后,在对函数指针执行间接访问前必须把它初始化为指向某个函数。
int f(int);
int (*pf)(int) = &f;//&可有可无,因为函数名被使用时总是被编译器转换成函数指针。
-----
三种方式调用函数:
int ans;
ans = f(25);//函数名f会首先被转换成一个函数指针,该指针指定函数在内存在的位置,然后函数调用操作符调用该函数执行开始于这个地址的代码;
ans = (*pf)(25);//把函数指针转换成一个函数名,这个转换并不是真正需要的,因为编译器在执行函数调用操作符之前又会把它转换回去。
ans = pf(25);
---------
回调函数 把一个函数指针作为参数传递给其他函数,后者将“回调”用户的函数。如果编写的函数必须能够在不同时刻执行不同类型的工作或者执行只能由函数调用者定义的工作,就可以使用这个技巧。
一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。
typedef void(*pcb)(char *);
回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。
被调函数的例子:
void GetCallBack(pcb callback)
{
/*do something*/
}
用户在调用上面的函数时,需要自己实现一个pcb类型的回调函数:
void fCallback(char *s)
{
/* do something */
}
然后,就可以直接把fCallback当作一个变量传递给GetCallBack,
GetCallBack(fCallback);
如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。
#include <stdio.h>
#include <stdlib.h>
int sort_function( const void *a, const void *b);
int list[5] = { 54, 21, 11, 67, 22 };
int main(void)
{
int x;
qsort((void *)list, 5, sizeof(list[0]), sort_function);
for (x = 0; x < 5; x++)
printf("%i/n", list[x]);
return 0;
}
int sort_function( const void *a, const void *b)
{
return *(int*)a-*(int*)b;
}
转移表:
swith(oper)
{
case ADD:result = add(op1,op2);break;
case SUB:result = sub(op1,op2);break;
case MUL:result = mul(op1,op2);break;
......
}
如果对于成千上万个操作,这个switch语句可能很长,所以,把具体操作和选择操作的代码分开是一种良好的设计方案。
创建一个转换表需要两个步骤。
首先声明并初始化一个函数指针数组。
留意确保这写函数的原型出现在这个数组的声明之前。
double add(double,double);
double sub(double,double);
double mul(double,double);
...
double (*oper_func[]) (double,double) = {add , sub, mul...}
初始化的列表中,各函数名的正确顺序取决于程序中用于表示每个操作符的整型代码 。
这里假定 ADD是0 ,SUB是1,MUL是2。。。
然后用下面语句:
result = oper_func [oper] (op1 , op2);
浙公网安备 33010602011771号