函数指针的重要用途——回调函数

什么是回调函数?

粗暴的说,如果一个函数作为另一个函数的参数传入,这种函数就可以称为回调函数(这句话并不严谨,但为了说明问题可以这么理解)。C语言里面,一般就是一个函数的参数列表中有函数指针,函数指针指向的函数就是一个回调函数。

为什么要有回调函数?

那为什么不直接在函数体内调用,而非要把函数指针作为参数呢?

举一个例子:系统提供一个排序函数sort(int a[ ]),排序函数默认升序,但如果我们想要降序排列呢?那系统还要提供一个降序版本?

显然,系统可以提供这样一个接口sort(int a[ ], void(p)(int) ),后者是一个指向排序方法的函数指针。用户可以自行定义排序方法。即,我们可以认为,回调函数有以下的功能:

  • 一个接口,可以实现不同的功能。这种思想不就是多态吗?本质上还是为了实现地址的晚绑定。C++中的仿函数,其实是对函数指针做了某种程度的简化,使用户使用更简单罢了,使用到的思想是一样的。
  • 通过回调函数可以修改一个黑盒子内部默认的功能,这也是业务上经常用的。

Linux操作系统用到了大量回调的思想,比如对于不同厂家提供的驱动,厂家按照Linux提供的接口标准编写自己的方法,而Linux接口的参数列表中就有指向对应方法的函数指针,这样尽管厂家不同,Linux也可以使用。

再举一个例子,默认情况下,当我们按下CTRL + C时,进程会终止。那我们想改变这样的默认行为怎么办,linux提供了signal这样一个接口。

 #include <signal.h>
  void (*signal(int sig, void (*func)(int)))(int);
</signal.h>

第一个参数是信号的编号,此处的ctrl + C对应的是2号信号,第二个参数就是一个函数指针,指向用户自己提供的方法。

如下面的这段代码:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void mysignal(int signo)
{
  printf("catch a signal! %d\n", signo);
}

int main()
{
  signal(2, mysignal);
  while(1)
  {
    printf("hello world!\n");
    sleep(1);
  }
  return 0;
}
</signal.h></unistd.h></stdio.h>

这段代码中,使用signal函数注册了一个新的方法,当按下ctrl + C时,不再默认终止进程,而是输出catch a signal! 2。效果如下:

函数指针的重要用途——回调函数

也就是说,系统提供接口用到了回调函数,用户定义该函数,实现了用户所需要的功能。这也是回调函数的主要应用方式。

Original: https://www.cnblogs.com/Grong/p/15642201.html
Author: 乌有先生ii
Title: 函数指针的重要用途——回调函数

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585751/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 记录一次docker镜像拉取失败的问题

    syslog日志 Mar 13 08:42:41 xxx dockerd[30691]: time=”2022-03-13T08:42:41.928436506Z&#8…

    Linux 2023年6月14日
    0144
  • Linux基线加固

    bash;gutter:true; 1、修改vsftp回显信息 (1)检查办法 修改vsftp回显信息: 需在安装VSFTP的情况下检查,未安装可忽略或禁用该项。 查看ftpd_b…

    Linux 2023年6月13日
    081
  • go语言接口

    接口在底层的实现有两个部分:type 和 data。 在源码中,显式地将 nil 赋值给接口时,接口的 type 和 data 都将为 nil。此时,接口与 nil 值判断是相等的…

    Linux 2023年6月13日
    064
  • CentOS 7 安装 mysql 5.7.27 for zabbix

    本文是因为需要安装zabbix系统,才贴出的此步骤,供自己查阅方便之用; 在安装使用zabbix前,需要先安装数据库,这里使用的是MySQL数据库进行部署,给出安装步骤,大家觉得有…

    Linux 2023年6月8日
    088
  • 理想汽车 x JuiceFS:从 Hadoop 到云原生的演进与思考

    理想汽车在 Hadoop 时代的技术架构 首先简单回顾下大数据技术的发展,基于我个人的理解,将大数据的发展分了4个时期: 第一个时期: 2006 年到 2008 年。2008 年左…

    Linux 2023年6月14日
    083
  • Firefox浏览器的一些配置

    一、在新标签页打开书签 1、打开Firefox浏览器,地址栏输入 about:config。 2、选择”接受风险并继续”。 3、搜索 browser.tab…

    Linux 2023年6月6日
    096
  • 八、网络管理

    常见查看网络命令ifconfigip addr showroute -n 查看路由(也可以查看网关)pingtraceroute www.sina.comarping -I eno…

    Linux 2023年6月7日
    0108
  • Linux Ubuntu 添加新用户

    1. 了解配置文件 Linux下与用户信息相关的配置文件有 /etc/passwd、 /etc/group、 /etc/shadow等,其权限分别如下: /etc/passwd:保…

    Linux 2023年6月14日
    087
  • WSL系统安装与使用

    WSL是适用于 Linux 的 Windows 子系统,可让开发人员按原样运行 GNU/Linux 环境 – 包括大多数命令行工具、实用工具和应用程序 – …

    Linux 2023年5月27日
    0127
  • Centos7最小化安装报错There are no enabled repos. Run “yum repolist all” to see the repos you have.解决办法

    原因是缺少CentOS-Base.repo文件,因为我这台机器wget也不能用,所以我是下载到本地sftp上去的,传输的时候一定要在root用户下,否则会无法启动传输 这是报错的完…

    Linux 2023年6月7日
    097
  • 关于ubuntu执行32位程序报错execvp():No such file or directory的解决方案

    一、前言 &#x5728;ubuntu 执行一个程序时,居然报错 execvp():No such file or directory ,报错截图如下图所示: ls -al…

    Linux 2023年6月8日
    094
  • 网络安全简单入门与扫描

    网络安全简单入门 内容大纲 策略制定 安全工具 其他 1、安全策略 1.1、安全三要素 要全面地认识一个安全问题,我们有很多种办法,但首先要理解安全问题的组成属性。前人通过无数实践…

    Linux 2023年6月7日
    084
  • centos 7 安装KVM

    一、安装KVM 实验环境如下: 虚拟机版本:VMware 12.5.7虚拟机需要开启虚拟化,如下图: 系统版本:CentOS Linux release 7.5.1804 (Cor…

    Linux 2023年6月7日
    086
  • RHCSA阶段笔记

    命令终端字段含义介绍 [root@localhost ~]# 解释: root:当前登录系统用户名(root超级管理员) localhost :当前主机名 :当前用户所在目录( 为…

    Linux 2023年5月27日
    078
  • 解决 Docker Push Skipped foreign layer 的错误

    引言当Docker推送基于Windows镜像到私有仓库的时候会遇到 Skipped foreign layer的问题。 docker push 192.168.2.30:5000/…

    Linux 2023年6月14日
    0100
  • shell编程学习

    在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。 ! 告诉系…

    Linux 2023年5月28日
    085
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球