1.函数指针
函数名被使用时总是由编译器把它转化成 函数指针。so:int func(int);then:int (*pf)(int) = &func;int (*pf)(int) = func;这两种是等价的to then:调用:int a ;a = f(25);a = (*pf)(25);a = pf(25);也是等价的
2.回调函数
假设我们要搜索链表的元素
Node * serch_list(Node* node , const int value);
这样的话我们就限定了搜索的链表存储的是整形元素,不够通用
更通用的做法是使查找函数与类型无关,这样就能用于任何类型的链表了
做法:
我们编写一个函数,用于比较两个值,然后把一个指向这个函数的函数指针作为参数传递给查找函数
然后被搜索函数调用,这个被调用的函数我们称为回调函数
还有一点:我们在上下文中为回调函数的函数原型.
所以,解决这个问题办法是:
把参数类型声明为void *
Node * serch_list(Node* node , const int value,int (*cmp)(const void *,const void *));
int cmp_int(void const *a ,void const *b)
{
return *((int *)a) - *((int *)b);
}
使用:
serch_list(root,1,compare_int);
注意强制转化:比较函数的参数必须声明为void *以匹配查找函数的原型,
然后他们再强转为 int *类型,用于比较整形。
注意:
在使用比较函数中的指针之前,他们必须强转为正确的类型。
因为强转能够躲过一般类型的检查,所以
使用的时候必须确认函数的参数是正确的。
如果我希望比较的是字符串,我就可以使用库函数中的strcmp
serch_list(root ,"abc",strcmp);
不过有些编译器会发出警告,因为它的参数声明为char *而不是void *;
c++ 错误(不知道如何解决)
不能将参数 1 从“int (__cdecl *)(const char *,const char *)”转换为“int (__cdecl *)(const void *,const void *)
3. 存放函数指针的
数组 (attention 是数组)
int ( *f[] )();
*f[] :首先是数组是某种类型的指针的数组
末尾(): 是表示函数调用的操作符。
f是一个数组,存放了返回值是int 的函数指针。
例子:
double add(double ,double);
double sub(double ,double);
double mul(double ,double);
double div(double ,double);
double ( *opt_fun[] )(double, double ) ={
add,sub,mul,div
}
result = oper_func[0](1,2);