这篇文章足以让你彻底明白C语言回调函数是

当说到回调函数,我先打个比方,在很多场景中,某个客户,拿着游戏项目想找某些游戏开发商合作,前提不知道他们的实力如何,先投石问路,然后在每家公司叫他们做好结构功能等设计,符合要求的我再投谁。对客户来说,我要的是先看看你们给我们写的代码是否有可维护性,可读性,可扩展性,灵活性,简洁性,可复用性,可测试性甚至是健全性等问题的慎重考虑。面对这些要求对开发商而言技术实力就显得更重要,写出符合客户要求的,在代码上,回调函数有时起着很关键性的作用。

回调函数的作用:

回调函数在程序开发中是一个非常重要的概念,所谓的回调其实就是不同程序模块之间的接口和约定,是软件分层设计的基本方式。只要是回调函数的使用可以在很大程度上提升编程的效率,所以很多场景开发中,有一些需求是必须要使用回调函数来实现的。同时,在C语言中,回调函数只能使用函数指针来实现,比如C++等语言还可以使用仿函数或匿名函数。

什么是回调函数?

在此我引用网络上的一段话,更加能通俗易懂:

回调函数是一种非常重要的机制,主要可以用来实现软件的分层设计,使得不同软件模块的开发者的工作进度可以独立出来,不受时空的限制,当需要的时候只需要通过约定好的接口(或者标准)相互契合在一起,也就是C++或者JAVA等现代编程语言声称的所谓面向接口编程。同时回调也是定制化软件的基石,通过回调机制将软件的前端和后端分离,前端提供逻辑策略,后端提供逻辑实现。

我们知道C语言中的函数实际上就相当于一个人,你给他一些参数,他帮你完成一样固定的功能,用厨师和医生比喻下:“比方我给厨师一道菜名,厨师就会把这道菜烹饪出来;你带一位病人给医生看,医生将会对这位病人进行医治等等。这里,厨师和医生都相当于功能确切的函数,等着你来调用它。

我们身边不乏有很多这样的“函数”,假设你每天都到食堂吃饭,发现每次去吃饭都要走很长的一段路程,会比较累,于是你就想让公司的前台同事去吃饭时顺便帮你打一盒饭回来。那么,在同事外出午餐之前,你就等于传递一些参数给你的同事(比方说:20块钱,以及说清楚你要吃什么,蛋炒饭还是西红柿炒饭等等),到半个小时后,这位同事经过了付款等操作后拿着热腾腾的盒饭回来给你了。这一系列的过程就是普通函数的调用过程。而你相当于调用了你的同事,实现了不用跑远路光坐着也能吃上饭的美好夙愿,这个过程就像下面一张图所示一样:

当然这还不够,还有下续:

毕竟每个人老是吃一家食堂的饭也是会腻的吧,最后导致你已经确定你无法再吃下去了,于是乎就决定不再吃食堂的饭了,改为自己做饭。这个做饭不能全由一个人来做,否则谈论这个回调就没啥意义了。所以还是继续要去调用前台同事帮我干活(似乎有劳累同事的感觉),老是叫人做事也怪不好意思的,所以叫人干活多少给点钱人家这还算过意得去。

把自己想吃的东西,让这位同事帮你去菜市场买回来,然后给做好,再端给你吃(似乎像保姆了,仅比喻~~)。虽然这位同事看起来非常愿意为你效劳的,愿意为你跑腿、买菜、砍价、端茶递水,到最后发现居然是一个不会做饭的人。在无奈之下,不麻烦同事了。有钱任性的你于是雇佣了一名资深大厨,啥也不会只会做饭的就行,你只要给他材料就行了。

就这样,啰嗦了一大堆,午饭做饭的过程:你将要吃的菜品清单和需要花的钱只传递给你的同事,甚至你还把大厨的电话号码给到同事那里,告诉他说:买了菜之后就打这个电话,让大厨帮你把菜做好了再给我送过来OK。与此同时,你可以“定制”你的大厨,你叮嘱你的大厨说:大厨,我喜欢重口味的还是清淡的,以后你做的任何菜里,都要放够足量的辣椒酱油盐还是少放清淡为止。就像如下图所示一样:

在上面为了吃个不易的午饭,也实现了典型的回调机制,你定制了一位大厨,然后你在调用同事的同时,也把大厨的电话号码也给到你同事,所以同事在需要做饭的时候,就会根据你提供的参数(大厨的电话)回过去调用(回调)那位大厨,把做好的饭菜端给你。

在上图中有一个最重要的信息就是:左边的两个人和右边的那个人之间有一条饱含深意的虚线,他意味着左右两边是两拨人,左边的人负责做饭和吃饭,右边的人负责跑腿、砍价等。比如:你只要知道怎么找到你的同事,传递给他参数让他干活就行了,根本不需要知道同事买的菜是从哪里买的,不管路程远还是近,另外也管好这位大厨,让他只做符合我口味好吃的饭菜就行,也根本不需要管买菜的同事什么时候会找大厨,甚至不管他们以后感情发展如何。对于右边的同事而言,他只要根据你的嘱咐去跑腿,在有必要的时候“回调”一下大厨就行,也根本不需要管大厨做的饭菜好不好吃,因为是做给我吃,口味由我决定。

所以上面图中左右两拨人就各司其职,互不耦合,独立性强,但又可以非常方便地相互合作,达成共识,能完成一个丰富的功能。这里,大厨就是一个回调函数——一个不被设计者(你自己)直接调用,而是被其他人(你的同事)回过来调用的函数。你传递给同事的电话号码,相当于一个能找到大厨的指针,被称之为"函数指针",回调机制就是靠传递函数指针来告知回调函数的位置的。

回调函数怎么写?

啰嗦了一堆,总算理解了什么是回调函数,现在看下简单的回调函数应该如何实现,就以代码形式演示利用回调函数查找数组中的元素是如何来实现的?如下所示:

#define_CRT_SECURE_NO_WARNINGS#includestdio.h#includestring.h#includestdlib.h//创建结构体structarrInfo{  charname[64];  intage;};//底层函数的实现intprintArr(void*arr,intelesize,intlen,void*date,int(*arrCompare)(void*,void*)){  char*p=arr;  for(inti=0;ilen;i++){    //获取到每个元素的首地址    char*arrAddr=p+elesize*i;    //如果用户输入的数据==数组中遍历的元素    if(arrCompare(date,arrAddr)){      return1;    }  }  return0;}//用户自己所提供的函数intmyConfig(void*d1,void*d2){  structarrInfo*p1=d1;  structarrInfo*p2=d2;  if(strcmp(p1-name,p2-name)==0p1-age==p2-age){    return1;  }  else{    return0;  }}voidtest(){  //查找数组中是否有指定类型的元素,如果有返回1,如果没有则返回0  structarrInfoarr[]=  {    {"Hello",},    {"World",},    {"Love",},    {"Chinese",}  };  intlen=sizeof(arr)/sizeof(structarrInfo);  structarrInfop={"World",};  intres=printArr(arr,sizeof(structarrInfo),len,p,myConfig);  if(res){    printf("找到数组中的元素\n");  }  else{    printf("未找到数组中的元素\n");  }}intmain(){  test();  return0;}

结果是找到此数组元素的,如下图所示:




转载请注明:http://www.aierlanlan.com/rzgz/4812.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了