回调函数

来源:互联网 发布:数据库存储过程作用 编辑:程序博客网 时间:2024/05/29 07:36
    回调函数

   回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。回调函数使用是必要的,在我们想通过一个统一接口实现不同的内容,这时用回掉函数非常合适。比如,我们为几个不同的设备分别写了不同的显示函数:void TVshow(); void ComputerShow(); void NoteBookShow()... 等等。这是我们想用一个统一的显示函数,我们这时就可以用回掉函数了。 void show(void (*ptr)()); 使用时根据所传入的参数不同而调用不同的回调函数。

  不同的编程语言可能有不同的语法,下面举一个 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);
}

int main()
{
  
     printf("************************\n");

      Caller1(Test1); //相当于调用 Test1();
      printf("&&&&&&************************\n");
  
     Caller2(30, Test2); //相当于调用 Test2(30);

      return 0;
}


 以上通过将回调函数的地址传给调用者从而实现调用,但是需要注意的是带参回调函数的用法。要实现回调,必须首先定义函数指针。函数指针的定义这里稍微提一下。比如: 
   int (*ptr)(); 这里 ptr 是一个函数指针,其中 (*ptr)的括号不能省略,因为括号的优先级高于星号,那样就成了一个返回类型为整型的函数声明了。



 // 例子2.
#include <stdlib.h>
#include <stdio.h>

#define METHOD  1

int Test1(void)
{
     int i;
     for(i=0; i<5; 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;
}


#ifdef METHOD
typedef int (* callback1)(void);

//typedef int (* callback2)(int); 这个声明也是ok 的.. 
typedef int (* callback2)(int num);

void Caller1( callback1 ptr )//指向函数的指针作函数参数
{
     printf("method 1------caller1............\n");
     ptr();
}

void Caller2(int n, callback2 ptr)//指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的,
{
     printf("method 1------caller1............\n");
     ptr(n);
}

#else

void Caller1( int (*ptr)() )//指向函数的指针作函数参数
{
     printf("method 2------caller1............\n");
     (*ptr)();
}

//以下三种方式定义都ok !!!!
//void Caller2(int n, int (*ptr)() )
//void Caller2(int n, int (*ptr)(int) )
void Caller2(int n, int (*ptr)(int num) )//指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的,
{
     printf("method 2------caller2............\n");
     //不能写成void Caller2(int (*ptr)(int n)),这样的定义语法错误。
     (*ptr)(n);
}

#endif

int main(void)
{
     printf("\n\n");
     printf("************************\n");
     Caller1(Test1); //相当于调用Test1();
     printf("\n\n\n");
     
     printf("&&&&&&************************\n");
     Caller2(8, Test2); //相当于调用Test2(30);
     printf("\n\n");
     
     return 0;
}


// 实例3
#include<stdio.h>

// 方法指针的格式为:int (*ptr)(char *p) 即:返回值(指针名)(参数列表)
typedef int (*CallBackFun)(char *p); // 为回调函数命名,类型命名为 CallBackFun,参数为char *p

int Afun(char *p) {    // 方法 Afun,格式符合 CallBackFun 的格式,因此可以看作是一个 CallBackFun
    printf("Afun ,callback print the string is :%s!\n", p);
    return 0;
}

int Cfun(char *p) {    // 方法 Bfun,格式符合 CallBackFun 的格式,因此可以看作是一个 CallBackFun
    printf("Cfun ,callback print the string is :%s, Nice to meet you!\n", p);
    return 0;
}

int call(CallBackFun pCallBack, char *p) { // 执行回调函数,方式一:通过命名方式
    printf("call method 1, the string is :%s!\n", p);
    pCallBack(p);
    return 0;
}

// int call2(char *p, int (*ptr)(char *p)) 
int call2(char *p, int (*ptr)()) { // 执行回调函数,方式二:直接通过方法指针
    printf("=======call method 2, the string is :=======\n", p); 
    (*ptr)(p); 
}

int main() {    

    char *p = "hello";

    call(Afun, p);
    call(Cfun, p);
    printf("\n");
    printf("\n");

    call2(p, Afun);
    call2(p, Cfun);
    printf("\n");
    printf("\n");
   
    
    // int i = getchar();
    // printf("Input: %c \n", i);

    return 0;
}



原创粉丝点击