回调函数

回调即是调用者A通过调用函数B,并且给B传递一个的函数指针参数C,让B反过来调用这个又调用者指定的函数指针函参C所指向的函数,这就是回调。简单点说,回调就是将函数指针作为函数参数,函数通过这个函数指针来调用另一函数的做法,这也是函数指针的一种用法——作为函数参数。

回调函数也是一个函数或过程,不过它是一个由调用方自己实现,供被调用方使用的特殊函数。回调函数可以像普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。所以回调函数就是一个函数,只不过它强调的是这个函数指针可以作为函数参数被回调。

回调的意义,可以让调用者制定或指定被调用函数的处理过程。如果用户传递了不同的值给函数参数,那么被调用函数将调用不同地址的函数,这样就能实现被调用函数与被调用函数不同实现方法的动态绑定。

回调函数的用处:如QT中的信号与槽函数的绑定函数connect()、linux中的信号处理函数signal()等;

                        除了这些已有的实现方法,我们还可以利用回调函数来实现函数的”多态“,实现不同功能的指定,或是同一功能不同类型参数的功能实现方法指定。

以下为例子:

用同一函数实现指定的不同功能:

double add(double a,double b);
double sub(double a,double b);
double mul(double a,double b);
double div(double a,double b);
double db_fun(double a,double b, double (*f)(double,double));
int main(void)
{
double a = 22.2,b = 11.1;
printf("a = %f,b = %f\n",a,b);//在printf 的时候double 用%f 和%lf 都可以,而scanf 时double 只能用%lf
printf("a+b=%lf\n",db_fun(a,b,add));
printf("a-b=%lf\n",db_fun(a,b,sub));
printf("a*b=%lf\n",db_fun(a,b,mul));
printf("a/b=%lf\n",db_fun(a,b,div));
return 0;
}
double db_fun(double a,double b, double (*f)(double,double))
{
	return (*f)(a,b);
}
double add(double a,double b)
{
	return a+b;
}
double sub(double a,double b)
{
	return a-b;
}
double mul(double a,double b)
{
	return a*b;
}
double div(double a,double b)
{
return a/b;
}
结果:
a = 22.200000,b = 11.100000
a+b=33.300000
a-b=11.100000
a*b=246.420000
a/b=2.000000

同一功能不同类型参数的功能实现指定:
void add(const void *a,const void *b,void *result,void  (*pf)(const void *a,const void *b,void *result));
void cadd(const void *a,const void *b,void *result);
void iadd(const void *a,const void *b,void *result);
void fadd(const void *a,const void *b,void *result);
void dadd(const void *a,const void *b,void *result);
int cmp(const void *a,const void *b, int (*pf)(const void *a,const void *b));
int ccmp(const void *a,const void *b);
int icmp(const void *a,const void *b);
int fcmp(const void *a,const void *b);
int dcmp(const void *a,const void *b);
int scmp(const void *s2,const void *s1);
int main(void)
{
	char ca = 'a',cb = 'e',c_result = 0;
	int ia = 5,ib = 7,i_result = 0;
	float fa = 5.6,fb = 4.8,f_result = 0;
	double da = 11.1,db = 9.9,d_result = 0;
	//add函数:
	add(&ca,&cb,&c_result,cadd);
	add(&ia,&ib,&i_result,iadd);
	add(&fa,&fb,&f_result,fadd);
	add(&da,&db,&d_result,dadd);
	printf("%c + %c = %c\n",ca,cb,c_result);
	printf("%d + %d= %d\n",ia,ib,i_result);
	printf("%f + %f = %f\n",fa,fb,f_result);
	printf("%lf + %lf = %lf\n",da,db,d_result);
       //cmp函数:
	int flag=0;
	const char *sa = "abcdif";
	const char *sb = "abcdifhmk";
	flag = cmp(&ca,&cb,ccmp);
	switch(flag)
	{
		case 1:printf("a > b\n"); break;
		case -1:printf("a < b\n");break;
		default :printf("a = b\n");break;
	}
	flag = cmp(&ia,&ib,icmp);
	switch(flag)
	{
		case 1:printf("a > b\n"); break;
		case -1:printf("a < b\n");break;
		default :printf("a = b\n");break;
	}
	flag = cmp(&fa,&fb,fcmp);
	switch(flag)
	{
		case 1:printf("a > b\n"); break;
		case -1:printf("a < b\n");break;
		default :printf("a = b\n");break;
	}
	flag = cmp(&da,&db,dcmp);
	switch(flag)
	{
		case 1:printf("a > b\n"); break;
		case -1:printf("a < b\n");break;
		default :printf("a = b\n");break;
	}
	flag = cmp(sa,sb,scmp);
	switch(flag)
	{
		case 1:printf("a > b\n"); break;
		case -1:printf("a < b\n");break;
		default :printf("a = b\n");break;
	}
	return 0;
}
//-------------------------------ADD--------------------------------------------------------------
void add(const void *a,const void *b,void *result,void  (*pf)(const void *a,const void *b,void *result))
{
         (*pf)(a,b,result);
}
void cadd(const void *a,const void *b,void *result)
{
	*((char *)result) = *(char *)a + *(char *)b;   //这里只是示范,而实际上字符相加很容易溢出127 或者是得到不可打印字符
}

void iadd(const void *a,const void *b,void *result)
{
	*((int *)result) = *(int *)a + *(int *)b;
}
void fadd(const void *a,const void *b,void *result)
{
	*((float *)result) = *(float *)a + *(float *)b;
}
void dadd(const void *a,const void *b,void *result)
{
	*((double *)result) = *(double *)a + *(double *)b;
}
//-------------------------------CMP---------------------------------------------------------------
int cmp(const void *a,const void *b, int (*pf)(const void *a,const void *b))
{
	return (*pf)(a,b);
}
int ccmp(const void *a,const void *b)
{
	if(*(char *)a == *(char *)b)
		return 0;
	else
		return *(char *)a > *(char *)b ? 1:-1;
}
int icmp(const void *a,const void *b)
{
	if(*(int *)a == *(int *)b)
		return 0;
	else
		return *(int *)a > *(int *)b ? 1:-1;

}
int fcmp(const void *a,const void *b)
{
	if(*(float *)a == *(float *)b)
		return 0;
	else
		return *(float *)a > *(float *)b ? 1:-1;

}
int dcmp(const void *a,const void *b)
{
	if(*(double *)a == *(double *)b)
		return 0;
	else
		return *(double *)a > *(double *)b ? 1:-1;
}
int scmp(const void *s1,const void *s2)
{
	if(s1 == NULL ||s2 == NULL)
	{
		printf("can't compare , the two string all are NULL !");
		return -2;
	}	
	else
		return strcmp((char *)s1,(char *)s2);
}
/*
结果:
a + e = //这里只是示范,而实际上字符相加很容易溢出127 或者是得到不可打印字符
5 + 7= 12
5.600000 + 4.800000 = 10.400000
11.100000 + 9.900000 = 21.000000
a < b
a < b
a > b
a > b
a < b




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值