美文网首页
C语言回调函数

C语言回调函数

作者: 大栗几 | 来源:发表于2020-05-21 13:20 被阅读0次

文章来源本人的博客:http://codelifeliwan.github.io/ 转载请注明出处

本代码和语言参考 李先静《系统程序员成长计划》。

回调函数就是由内部实现统一接口,由调用者来决定调用哪一个函数,是对C语言函数指针的一个高级应用。比如我们在Linux内核里面,在设备驱动里面,例如有两个不一样的字符设备。那么对这个设备执行刷新操作(不管是否有刷新操作,这里只举例)需要调用一定的函数,这两个设备所执行的函数一定是不同的。但是,上层的管理数据结构是一样的,在管理数据结构里面分别存入两个刷新操作的函数指针,那么在调用的时候就可以直接用统一接口来执行刷新操作即可。这就是回调函数的一个例子,他实现了传说中的Write Once,Run Anywhere.同时维护起来跟其他的相比更简单。

那么就看看书上的例子:实现一个双向链表(通用链表),它有遍历链表、统计链表中最大值和链表值求和的功能。这三个功能可以写成三个不同也不相关的函数,但是我们可以想到,这三个函数都有着相同的操作,那就是依次遍历。那么就可以将这个遍历抽出来(代码中的dlist_foreach函数),然后根据这三个函数的各自的功能来实现较少重复的代码。 具体代码请看下面:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
 
typedef struct _DListNode{
    struct _DListNode *prev;
    struct _DListNode *next;
    void *data;
}DListNode;
 
typedef void (*DListFunc)(void *ctx,void *data);
 
 
void add_dlist_node_int(DListNode *root,DListNode *p){
    if(root==NULL)return;
    if(p==NULL)return;
    p->next=root->next;
    p->prev=root;
    root->next=p;
}
 
void delete_dlist_node(DListNode *d){
    if(NULL==d)return;
    print_int(NULL,d);
    d->prev->next=d->next;
    d->next->prev=d->prev;
    free(d->data);
    free(d);
    d=NULL;
}
 
void init(DListNode **root){
    int i=0;
    int *tmp=NULL;
    *root=(DListNode*)(malloc(sizeof(DListNode)));
    (*root)->data=(int *)(malloc(sizeof(int)));
    *((int *)(*root)->data)=-1;
    (*root)->next=(*root)->prev=*root;
    for(i=0;i<10;i++){
        DListNode *p=(DListNode *)(malloc(sizeof(DListNode)));
        tmp=(int *)(malloc(sizeof(int)));
        *tmp=i;
        p->data=tmp;
        add_dlist_node_int(*root,p);
    }
}
 
void dlist_foreach(DListNode *thiz,DListFunc visit,void *context){
    DListNode *iter=NULL;
    if(NULL==thiz)return;
    iter=thiz->next;
    while(iter!=NULL&&iter!=thiz){
        visit(context,iter);
        iter=iter->next;
    }
}
 
void print_int(void *thiz,DListNode *d){
    printf("======%d\n",*((int *)(d->data)));
}
 
void sum_cb(void *thiz,DListNode *d){
    (*(int *)(thiz))+=*((int *)(d->data));
}
 
void find_max(void *thiz,DListNode *d){
    int a1=*((int *)(thiz));
    int a2=*((int *)(d->data));
    if(a1<a2){
        *((int *)thiz)=a2;
    }
}
 
void destroy(DListNode **root){
    DListNode *iter1=NULL,*iter2=NULL;
    if(NULL==(*root))return;
    iter1=*root;
    while(iter1!=NULL){
        iter2=iter1->next;
        if(iter2==iter1)iter2=NULL;
        delete_dlist_node(iter1);
        iter1=iter2;
    }
}
 
int main()
{
    DListNode *root=NULL;
    int tmp=0;
    init(&root);
    if(root==NULL){
        printf("Root id NULL!\n");
    }
    dlist_foreach(root,print_int,&tmp);
    tmp=0;
    dlist_foreach(root,sum_cb,&tmp);
    printf("SUB IS: %d\n",tmp);
    tmp=0;
    dlist_foreach(root,find_max,&tmp);
    printf("MAX IS: %d\n",tmp);
 
    destroy(&root);
}

相关文章

  • C语言回调函数

    文章来源本人的博客:http://codelifeliwan.github.io/ 转载请注明出处 本代码和语言参...

  • [C]基础语法

    [C语言]数据结构 STRUCT 结构体 位域 ERUM 枚举语法定义格式 回调函数 C语言中的回到函数 Defi...

  • 30/70 C语言回调函数

    layout: "post"title: "30/70 C语言回调函数"date: "2017-03-29 21:...

  • 2020-04-25 编程语言 经他么 整词儿

    静态语言:c/c++ 回调或虚函数? 迭代:tm什么意思? 生成器:tm什么意思?

  • UI(二十)block

    *block代码块 闭包(一个区域)与C语言函数类似 *block具有反向传值、回调的功能 回调:执行完毕之后返回...

  • iOS - block

    *block代码块闭包(一个区域)与C语言函数类似 *block具有反向传值、回调的功能 回调:执行完毕之后返回再...

  • c++11 之回调函数

    什么是回调函数,以及在c++中如何使用? 回调函数就是将函数 作为参数传给其他的函数。 c++ 中有三种方式实现:...

  • C语言回调函数学习

    转载自 https://blog.csdn.net/farsight2009/article/details/47...

  • block基础-1

    block块是在ios4开始,就出现了。block实质就是C语言的回调函数。block函数定义如下 void (^...

  • C回调函数

网友评论

      本文标题:C语言回调函数

      本文链接:https://www.haomeiwen.com/subject/vayzohtx.html