C语言

2023-11-11

1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取!

函数指针有两种常用的用法,一种是作为结构体成员,关于函数指针作为结构体成员的用法可移步至上一篇【C语言笔记】函数指针作为结构体成员进行查看。另一种是函数指针作为函数的参数。这一篇分享的是函数指针作为函数的参数。

一、函数指针作为函数的参数

函数指针可以作为一个参数传递给另一个函数。这时函数指针的使用就像普通的常量和变量一样。当函数指针作为参数传递的时候,这时接收参数传递的函数通常需要根据这个指针调用这个函数。作为参数传递的函数指针通常表示回调函数(Callback Functions)

1、什么是回调函数?

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

2、回调函数在实际中有什么作用?

先假设有这样一种情况:我们要编写一个库,它提供了某些排序算法的实现(如冒泡排序、快速排序等等),为了能让库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,能让库可用于多种数据类型(int、float、string),此时,该怎么办呢?可以使用函数指针,并进行回调。

例如,在C语言的通用工具库stdlib.h中,有如下一个函数原型:

void qsort(void *, size_t, size_t, int (comp*)(const void *, const void *))

这是在C通用工具库中声明的一个快速排序算法函数,其可以用来排序int类型、float类型以及字符串数据,可以按从小到大的顺序也可以按从大到小的顺序排序。其关键在于函数指针comp指向的函数的具体实现。

二、举例说明

上一节我们使用函数指针作为结构体成员来实现四则运算,这里一节我们稍微修改一下代码,使用函数指针作为函数参数来实现四则运算。

设计如下函数:

int calculate(int a, int b, fun_t operation)
{
 int result;
 result = operation(a, b); // 运算
 return result;
}

其中,fun_t是一个函数指针,其定义为:

typedef int (*fun_t)(int, int);

该函数指针fun_t指向一个带两个int类型的形参、int类型的返回值的函数。使用关键字typedefint (*)(int, int)进行重命名(封装)为fun_t。关于typedef与define的区别可查看往期笔记:【C语言笔记】#define与typedef的区别?

根据函数指针变量operation指向不同的运算函数可实现加法运算、减法运算、乘法运算、除法运算。

主函数代码如下:

int main(void)
{
 int result;
 int a = 192, b = 48;

 /* 两个数相加的操作 */
 result = calculate(a, b, add2);
 printf("加法运算: %d+%d = %d\n",a, b, result);
 
 /* 两个数相减的操作 */
 result = calculate(a, b, sub2);
 printf("减法运算: %d-%d = %d\n",a, b, result);
 
 /* 两个数相乘的操作 */
 result = calculate(a, b, mul2);
 printf("乘法运算: %d*%d = %d\n",a, b, result);
 
 /* 两个数相除的操作 */
 result = calculate(a, b, div2);
 printf("除法运算: %d/%d = %d\n",a, b, result);
 
 return 0;
}

实现运算的4个函数很简单,如下:

int add2(int a, int b)
{
 return a+b;
}

int sub2(int a, int b)
{
 return a-b;
}

int mul2(int a, int b)
{
 return a*b;
}

int div2(int a, int b)
{
 return a/b;
}

程序运行结果为:

VHQH6x.md.png

以上就是关于函数指针作为函数参数的笔记,如有错误欢迎指出!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言 的相关文章

随机推荐

  • Git第十四讲 Git标签管理

    Git标签是用于标记项目中的特定版本的重要工具 它们通常用于标识发布版本或里程碑 本文将介绍如何在Git中创建 查看和管理标签 创建标签 要在Git中创建一个标签 可以使用git tag命令 有两种类型的标签 轻量标签和附注标签 轻量标签
  • ML/DL-复习笔记【十】- 分组卷积和深度可分离卷积的区别

    本节为ML DL 复习笔记 十 分组卷积和深度可分离卷积的区别 主要内容包括 分组卷积与深度可分离卷积的参数量分析 最早出现分组卷积是AlexNet 由于单块GPU显存的限制 需要将网络部署在两张显卡上 分别进行训练最后再融合 Alex认为
  • 鸿蒙出来后H5足以取代原生app

    本地模式的H5渲染效果 其实已经在性能上无限接近于原生 也就是说当你使用file 而非http 访问H5页面的时候 打开速度也是非常快的 而且现在安卓和ios里面 提供了js访问原生代码的能力 目前有很多H5开发框架 集成了访问原生的能力
  • 在线标签云词云

    易词云 https www yciyun com 优点 可显示中文词条 可下载 缺点 字体大小控制不精准 下载高清图像要收费 wordart https wordart com 优点 免费 功能强大 缺点 不可以显示中文 可能需要添加中文字
  • 凌晨睡不着,想起了童年,写首诗吧,就叫《童年》

    雪夜里轻快又谨慎的踩雪声 印出稚嫩的脚印 一个胆大又怯懦的孩童 把手电筒插在帽兜里当做矿灯照明 微声哼着只有自己能听到的歌 沧桑的锁有节奏地拍打着大门 发出心里人的归家之念 炕上坐着的妇女 闻声而来 夏日晌午的小孩 在庭院里逗着毛虫 趁着无
  • SOTA模型训练笔记(完善中)

    文章目录 记录感知SOTA模型训练的过程 1 语义分割 1 PolarNet 2 Cylinder3D 2 视觉人体姿态识别 1 ViTPose 3 点云目标检测 1 centerpoint 记录感知SOTA模型训练的过程 1 语义分割 1
  • windows 使用docker安装elasticsearch报错

  • 使用ensp搭建简单校园网拓扑

    使用ensp搭建简单校园网拓扑 一 校园网拓扑 1 每台电脑代表一个vlan 2 二层交换机向下的每个端口需要做access 向上的每个端口需要做trunk 3 三层交换机向下的每个端口需要做trunk 而且需要为每个vlan接口配置ip地
  • Intellij IDEA2017.3.5安装

    1 下载安装包及 链接 https pan baidu com s 16az6tmQub bOn2CFOXLa2g 提取码 7689 复制这段内容后打开百度网盘手机App 操作更方便哦 2 将下载的JetbrainsCrack 2 7 re
  • js中(...)用法

    1 深拷贝一个对象 如上图所示 obj和tmp是完全两个独立的对象 互不影响 2 数组复制 3 函数形参中的使用 这里的 args 是对test函数中多余的参数进行收集 并转换成数组的形式进入函数体中 4 一种特殊情况 当数组里面套对象的时
  • sql 时间函数(全)

    Cite http www jb51 net article 20832 htm 1 当前系统日期 时间 select getdate 2 dateadd 在向指定日期加上一段时间的基础上 返回新的 datetime 值 例如 向日期加上2
  • C++结构体对齐问题

    规则1 结构体成员的内部偏移量 内部地址 要被这个成员的数据类型大小整除 规则2 整个结构体的大小 必须是最大成员的size整数倍 否则就需要在末尾补充空白字节 规则3 对于结构体中的结构体 按照结构体展开之后的内存对齐来处理 规则4 人为
  • 余老师带你学习大数据框架全栈第十三章Hudi第一节核心技术

    1 前言 1 1为什么产生数据湖 数据量比较大 越来越不满足处理结构化的数据 比如说数仓 数仓就是处理结构化数据 什么是结构化数据 就是数据成数据库来的 传统型的数据库有 MySQL数据库 Oracle SQLserver 从这些库里面过来
  • TensorFlow基础(1)-中使用多个 Graph

    代码中有时候会遇到 with tf Graph as default 其实这个可以有也可以没有 可能是可以让自己的思路更加清楚吧 知道这里开始新建图了 tensorflow官方教程 翻译 简介 当我们训练一个模型时 通常的做法是用一个 Gr
  • 公开课机器学习笔记(13)支持向量机三 核函数

    2 2 核函数Kernel 2 2 1 特征空间的隐式映射 核函数 咱们首先给出核函数的来头 在上文中 我们已经了解到了SVM处理线性可分的情况 而对于非线性的情况 SVM 的处理方法是选择一个核函数 通过将数据映射到高维空间 来解决在原始
  • DCL详解

    一 什么是DCL问题 在Java中 DCL通常指的是Double Checked Locking 双重检查锁定 DCL是一种用于多线程环境下懒加载单例对象的技术 它的基本思路是在对象还未被实例化时 先通过一次判空 避免了每次获取对象时都需要
  • JavaScript 数组find() 方法

    定义和用法 find 方法返回通过测试 函数内判断 的数组的第一个元素的值 find 方法为数组中的每个元素都调用一次函数执行 当数组中的元素在测试条件时返回 true 时 find 返回符合条件的元素 之后的值不会再调用执行函数 如果没有
  • C++指针的用法/指针与引用的区别

    指针的简介 计算机程序本质上是对存储在内存中的数据进行的一系列操作 既然要对数据进行操作 首先要解决的第一个问题就是数据存储在什么地方 一般情况下我们通过int x 10 来定义一个变量 可以通过x来直接访问该变量存储的值 而指针提供了另外
  • 启动和关闭ADB服务(adb start-server和adb kill-server)

    经作者测试 模拟器在运行一段时间后 adb服务有可能 在Windows进程中可找到这个服务 该服务用来为模拟器或通过USB数据线连接的真机服务 会出现异常 这时需要重新对adb服务关闭和重启 当然 重启Eclipse可能会解决问题 但那比较
  • C语言

    1024G 嵌入式资源大放送 包括但不限于C C 单片机 Linux等 关注微信公众号 嵌入式大杂烩 回复1024 即可免费获取 函数指针有两种常用的用法 一种是作为结构体成员 关于函数指针作为结构体成员的用法可移步至上一篇 C语言笔记 函