回调函数


什么是回调函数?


  

简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另


一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。


  为什么要使用回调函数?

  因为可以把调用者与被调用者分开。调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某


种特定原型、某些限制条件(如返回值为int)的被调用函数。


  如果想知道回调函数在实际中有什么作用,先假设有这样一种情况,我们要编写一个库,它提供了某些排


序算法的实现,如冒泡排序、快速排序、shell排序、shake排序等等,但为使库更加通用,不想在函数中嵌入


排序逻辑,而让使用者来实现相应的逻辑;或者,想让库可用于多种数据类型(int、float、string),此时,


该怎么办呢?可以使用函数指针,并进行回调。


  回调可用于通知机制,例如,有时要在程序中设置一个计时器,每到一定时间,程序会得到相应的通知,


但通知机制的实现者对我们的程序一无所知。而此时,就需有一个特定原型的函数指针,用这个指针来进行回


调,来通知我们的程序事件已经发生。实际上,SetTimer() API使用了一个回调函数来通知计时器,而且,万一


没有提供回调函数,它还会把一个消息发往程序的消息队列。


  另一个使用回调机制的API函数是EnumWindow(),它枚举屏幕上所有的顶层窗口,为每个窗口调用一个程


序提供的函数,并传递窗口的处理程序。如果被调用者返回一个值,就继续进行迭代,否则,退出。


EnumWindow()并不关心被调用者在何处,也不关心被调用者用它传递的处理程序做了什么,它只关心返回


值,因为基于返回值,它将继续执行或退出。


  不管怎么说,回调函数是继续自C语言的,因而,在C++中,应只在与C代码建立接口,或与已有的回调接


口打交道时,才使用回调函数。除了上述情况,在C++中应使用虚拟方法或函数符(functor),而不是回调函


数。


回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。回调函数使用


是必要的,在我们想通过一个统一接口实现不同的内容,这时用回掉函数非常合适。比如,我们为几个不同的


设备分别写了不同 的显示函数:void TVshow(); void ComputerShow(); void NoteBookShow()...


等 等。这是我们想用一个统一的显示函数,我们这时就可以用回调函数了。void show(void (*ptr)()); 使


用时根据所传入的参数不同而调用不同的回调函数。 


下面举两个例子说明回调该函数的使用

#include<stdio.h>
#include<stdlib.h>
void perfect(int n)
{
 int i=1;
    int count=0;
 for(i=1;i<n;i++)
 {
     
  if(0==n%i)
  {
   count+=i;
  }
 }
 if(count==n)
  printf("%d是完数\n",n);
 else printf("%d不是完数\n",n);
}
void myCallback(void (*perfect)(int ),int n)
{
 perfect(n);
}

int main()
{
 int n;
 printf("请输入一个正整数\n");
 scanf("%d",&n);

 myCallback(perfect,n);
 return 0;
 
}

//Test.c 
#include <stdlib.h> 
#include <stdio.h> 
int Test1() 
{ 
  int i; 
  for (i=0; i<30; i++) 
  { 
    printf("The %d th charactor is: %c\n", i, (char)('a' + i%26)); 

  } 
  return 0; 
} 
int Test2(int num) 
{ 
  int i; 
  for (i=0; i<num; i++) 
  { 
   printf("The %d th charactor is: %c\n", i, (char)('a' + i%26)); 

  } 
  return 0; 
} 
void Caller1(void (*ptr)())//指向函数的指针作函数参数 
{ 
  (*ptr)(); 
} 
void Caller2(int n, int (*ptr)())//指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的, 
{                                               //不能写成void Caller2(int (*ptr)(int n)),这样的定义语法错误。 
  (*ptr)(n); 
  return; 
} 
int main() 
{ 
  printf("************************\n"); 
  Caller1(Test1); //相当于调用Test2(); 
  printf("&&&&&&************************\n"); 
  Caller2(30, Test2); //相当于调用Test2(30); 
  return 0; 
} 

以上通过将回调函数的地址传给调用者从而实现调用,但是需要注意的是带参回调函数的用法。要实现回调,


必须首先定义函数指针。函数指针的定义这里稍微提一下。比如: int (*ptr)(); 这里ptr是一个函数指针,其


中(*ptr)的括号不能省略,因为括号的优先级高于星号,那样就成了一个返回类型为整型的函数声明了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值