1. 函数指针的应用例(1)
#include <stdio.h>
void MyFun1(int x);
void MyFun2(int x);
void MyFun3(int x);
typedef void (*FunType)(int ); // 定义一个函数指针类型FunType,与①函数类型一至
void CallMyFun(FunType fp,int x);
int main(int argc, char* argv[])
{
CallMyFun(MyFun1,10); //⑤. 通过CallMyFun函数分别调用三个不同的函数
CallMyFun(MyFun2,20);
CallMyFun(MyFun3,30);
}
void CallMyFun(FunType fp,int x) //③. 参数fp的类型是FunType。
{
fp(x);//④. 通过fp的指针执行传递进来的函数,注意fp所指的函数是有一个参数的
}
void MyFun1(int x) // ①. 这是个有一个参数的函数,以下两个函数也相同
{
printf("函数MyFun1中输出:%d\ni",x);
}
void MyFun2(int x)
{
printf("函数MyFun2中输出:%d\n",x);
}
void MyFun3(int x)
{
printf("函数MyFun3中输出:%d\n",x);
}
2. 函数指针应用例(2)
- #include<stdio.h>
- typedefint(*FP_CALC)(int,int);
- //注意这里不是函数声明而是函数定义,它是一个地址,你可以直接输出add看看
- int add(inta,intb)
- {
- returna + b;
- }
- int sub(inta,intb)
- {
- returna - b;
- }
- int mul(inta,intb)
- {
- returna * b;
- }
- int div(inta,intb)
- {
- returnb? a/b : -1;
- }
- //定义一个函数,参数为op,返回一个指针。该指针类型为 拥有两个int参数、
- //返回类型为int 的函数指针。它的作用是根据操作符返回相应函数的地址
- FP_CALC calc_func(charop)
- {
- switch(op)
- {
- case'+':returnadd;//返回函数的地址
- case'-':returnsub;
- case'*':returnmul;
- case'/':returndiv;
- default:
- returnNULL;
- }
- returnNULL;
- }
- //s_calc_func为函数,它的参数是 op,
- //返回值为一个拥有两个int参数、返回类型为int 的函数指针
- int (*s_calc_func(charop)) (int,int)
- {
- returncalc_func(op);
- }
- //最终用户直接调用的函数,该函数接收两个int整数,和一个算术运算符,返回两数的运算结果
- int calc(inta,intb,charop)
- {
- FP_CALC fp = calc_func(op); //根据预算符得到各种运算的函数的地址
- int(*s_fp)(int,int) = s_calc_func(op);//用于测试
- // ASSERT(fp == s_fp); // 可以断言这俩是相等的
- if(fp)returnfp(a, b);//根据上一步得到的函数的地址调用相应函数,并返回结果
- elsereturn-1;
- }
- void main()
- {
- inta = 100, b = 20;
- printf("calc(%d, %d, %c) = %d\n", a, b,'+', calc(a, b,'+'));
- printf("calc(%d, %d, %c) = %d\n", a, b,'-', calc(a, b,'-'));
- printf("calc(%d, %d, %c) = %d\n", a, b,'*', calc(a, b,'*'));
- printf("calc(%d, %d, %c) = %d\n", a, b,'/', calc(a, b,'/'));
- }
以上讲的是函数指针,也可以这样用:
#include <stdio.h>
void say_hello(const char *str)
{
printf("Hello %s\n", str);
}
int main(void)
{
void (*f)(const char *) = say_hello;
f("Guys");
return 0;
}
除了函数指针,普通函数也可以用typedef,如:
typedef int F (void);//定义函数类型F
之后可以这样声明:
F f,g;相当与声明
int f(void);
int g(void);
下面这个函数声明是错误的:
F h(void);
因为函数可以返回void
类型、标量类型、结构体、联合体,但不能返回函数类型,也不能返回数组类型。而下面这个函数声明是正确的:
F *e(void);
函数e
返回一个F *
类型的函数指针。如果给e
多套几层括号仍然表示同样的意思:
F *((e))(void);
但如果把*
号也套在括号里就不一样了:
int (*fp)(void);
这样声明了一个函数指针,而不是声明一个函数。fp
也可以这样声明:
F *fp;
顺便提下指针函数:
【指针函数】
一个函数不仅可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。
返回指针的函数,一般定义格式为:
类型标识符 *函数名(参数表)
int *f(x,y);
其中x,y是形式参数,f是函数名,调用后返回一个指向整型数据的地址指针。f(x,y)是函数,其值是指针。
如:char *ch();表示的就是一个返回字符型指针的函数,请看下面的例题:
【例】将字符串1(str1)复制到字符串2(str2),并输出字符串2.
#include "stdio.h"
main()
{
char *ch(char *,char *);
char str1[]="I am glad to meet you!";
char str2[]="Welcom to study C!";
printf("%s",ch(str1,str2));
}
char *ch(char *str1,char *str2)
{
int i;
char *p;
p=str2
if(*str2==NULL) exit(-1);
do
{
*str2=*str1;
str1++;
str2++;
}while(*str1!=NULL);
return(p);
}
通过分析可得
函数指针是一个指向函数的指针,而指针函数只是说明他是一个返回值为指针的函数,
函数指针可以用来指向一个函数。
回调函数
如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(Callback Function)。例如qsort(3)
和bsearch(3)
。
回调函数示例:void func(void (*f)(void *), void *p);
调用者 实现者
|
|