学懂C语言(二十一):深入理解C语言中的函数指针和回调函数

        C语言中的函数指针和回调函数是两个紧密相关的概念,它们在实现灵活和模块化的代码结构时非常有用。下面详细讲解这两个概念:

1、函数指针

函数指针是一个指向函数的指针变量。通过函数指针,可以间接调用函数,这在需要动态选择和调用不同函数时非常有用。

声明函数指针

函数指针的声明需要指定函数的返回类型和参数列表。

返回类型 (*指针变量名)(参数列表);

示例
#include <stdio.h>int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}int main() {int (*fp)(int, int); // 声明一个函数指针fp = add; // 将add函数的地址赋值给函数指针fpprintf("Add: %d\n", fp(3, 4)); // 输出7fp = subtract; // 将subtract函数的地址赋值给函数指针fpprintf("Subtract: %d\n", fp(3, 4)); // 输出-1return 0;
}

在这个示例中,fp是一个函数指针,它可以指向不同的函数(如addsubtract),并通过fp调用这些函数。

2、回调函数

回调函数是一种通过函数指针调用的函数。回调函数通常作为参数传递给其他函数,使得这些函数能够在特定事件或条件发生时调用回调函数。

示例:

#include <stdio.h>// 定义一个回调函数类型
typedef void (*callback_func)(int);// 接受一个回调函数作为参数的函数
void perform_operation(callback_func callback, int value) {callback(value); // 调用回调函数
}// 回调函数实现
void print_value(int value) {printf("Value: %d\n", value);
}int main() {perform_operation(print_value, 10); // 传递回调函数和参数return 0;
}

在这个示例中

  1. callback_func是一个函数指针类型,它指向一个接受int参数并返回void的函数。
  2. perform_operation函数接受一个callback_func类型的函数指针和一个整数值作为参数。
  3. perform_operation函数内部,通过函数指针callback调用回调函数。
  4. print_value是一个回调函数,它被传递给perform_operation并在其中被调用。

3、函数指针和回调函数的应用

  1. 动态函数调用:通过函数指针可以在运行时选择和调用不同的函数,增加程序的灵活性。
  2. 事件驱动编程:在事件驱动编程中,回调函数用于处理特定事件,如用户输入、定时器触发等。
  3. 排序和搜索算法:在排序和搜索算法中,可以通过回调函数自定义比较逻辑。
  4. 插件和模块化设计:在插件和模块化设计中,回调函数用于实现扩展点和自定义行为。

4、注意事项

  1. 函数指针的类型匹配:确保函数指针的返回类型和参数列表与目标函数匹配,否则会导致未定义行为。
  2. 空指针检查:在使用函数指针前,应检查其是否为NULL,避免调用无效的函数地址。

通过以上讲解,你应该对C语言中的函数指针和回调函数有了深入的理解。掌握这两个概念对于编写灵活、可扩展和模块化的C程序非常重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 小数取余 rem 和 mod有 bug

目录 前言Matlab取余函数1 mod 函数1.1 命令行输入1.2 命令行输出 2 rem 函数2.1 命令行输入2.2 命令行输出 分析原因注意 前言 在 Matlab 代码中mod(0.11, 0.1) < 0.01 判断为真&#xff0c;mod(1.11, 0.1) < 0.01判断为假&#xff0c;导致出现意料外的结果。 结果发现…

Leetcode509. 斐波那契数(递归和常规两种写法)

问题描述&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;…

代码自动化重构工具OpenRewrite介绍

OpenRewrite 是一个用于大规模自动化代码重构的开源框架&#xff0c;它极大地提升了开发人员的研发效率&#xff0c;通过自动化地进行代码重构和转换&#xff0c;帮助开发人员消除代码库中的技术债务。 通过 LST、访问器和配方的结合&#xff0c;OpenRewrite 能够实现准确的代…

Python知识点背诵手册,详细知识梳理

Python知识点背诵手册&#xff0c;超详细知识梳理 Python是一种广泛使用的高级编程语言&#xff0c;以其简洁的语法和强大的库支持而闻名。以下是对Python知识点的超详细梳理&#xff0c;旨在帮助学习者系统地掌握Python语言的基础知识和进阶技能。 一、Python基础 1. 语言基…

走进数组的奇妙之旅(1)-学习笔记

引言&#xff1a; 在前几篇文章中&#xff0c;我们深入探讨了函数的奥秘。在讲述函数知识的过程中&#xff0c;我们邂逅了一个新的概念&#xff0c;你或许还记得在演示 strcpy函数时&#xff0c;出现的这行代码&#xff1a;char1[20]{0};。当时&#xff0c;你是否感到好奇&…

【MSP430】MSP430是什么?与STM32对比哪个性能更佳?

一、MSP430是什么&#xff1f; MSP430F5529LP是一款由德州仪器&#xff08;TI&#xff09;推出的16位微控制器单元&#xff08;MCU&#xff09;开发板&#xff0c;具有USB功能&#xff0c;内存配置为128KB闪存和8KB RAM&#xff0c;工作频率高达25MHz。 这款MCU以其高性能和多…

软考中级网络工程师考什么?应该怎么正确备考

网络工程师软考中级难易度50%&#xff0c;不太难。但是如果准备不足就悬了&#xff0c;赶紧备考起来吧。 网络工程师每年考两次&#xff0c;相比其他的软考考试一年中考的机会又多了一次&#xff0c;而且软考网工也是挺热门的科目&#xff0c;每年很多人报考&#xff0c;相对的…

视觉语言动作模型:从网页知识到机器人控制的实战RT-2

作者&#xff1a; Anthony Brohan, Noah Brown, Justice Carbajal, Yevgen Chebotar, Xi Chen, Krzysztof Choromanski, Tianli Ding, Danny Driess, Avinava Dubey, Chelsea Finn, Pete Florence, Chuyuan Fu, Montse Gonzalez Arenas, Keerthana Gopalakrishnan, Kehang Han…

【深度学习】PyTorch框架(5):Transformer和多注意力机制

1、引言 在本文中&#xff0c;我们将探讨近两年来最具影响力的模型架构之一——Transformer模型。自从2017年Vaswani等人发表的论文《注意力是你所需要的全部》以来&#xff0c;Transformer架构在多个领域持续刷新着性能记录&#xff0c;尤其是在自然语言处理&#xff08;NLP&…

DEF_COLOR.py 终端打印显示颜色(Linux/Windows)

打印内容一多&#xff0c;不用颜色区分看着吃力 # -*- coding: utf8 -*- import os## 终端显示颜色 if os.name nt: # Windowsimport ctypes,sysSTD_OUTPUT_HANDLE -11# Windows CMD命令行 字体颜色定义 text colors黑字 0x00 # black.暗蓝字 0x01 # dark blue.暗绿…

C++学习补充2:MySQL select 查询

MySQL select 查询 MySQL 查询 select时&#xff0c; 不区分大小写的。 MySQL 在默认情况下是区分大小写的&#xff0c;但是它的行为可能因配置和使用的字符集而有所不同。以下是一些可能导致查询在 SELECT 语句中不区分大小写的原因&#xff1a; 字符集设置&#xff1a;如果…

释放硬件潜能:Xcode中应用硬件加速开发的深度指南

释放硬件潜能&#xff1a;Xcode中应用硬件加速开发的深度指南 在现代应用开发中&#xff0c;充分利用硬件资源是提升应用性能的关键。Xcode&#xff0c;作为苹果的官方集成开发环境&#xff08;IDE&#xff09;&#xff0c;提供了强大的工具和框架来支持硬件加速开发。本文将详…

CSI-RS在信道中传输的过程

简单介绍CSI-RS信号生成&#xff0c;在信道中传输和接收的过程 1.载波配置 首先需要配置载波相关的参数 系统带宽和子载波间隔 5G NR中&#xff0c;系统带宽和子载波间隔是两个关键参数&#xff0c;共同决定无线资源的分配和使用 系统带宽 5G NR支持广泛的系统带宽&…

Xcode应用开发:自定义图表的终极指南

Xcode应用开发&#xff1a;自定义图表的终极指南 在移动应用开发中&#xff0c;图表是一种展示数据的强大工具&#xff0c;它可以帮助用户直观地理解复杂信息。Xcode&#xff0c;作为苹果官方的集成开发环境&#xff08;IDE&#xff09;&#xff0c;提供了丰富的工具和框架来创…

碳酸锂溶液树脂吸附除钙镁的方法和工艺流程

碳酸锂溶液作为一种重要的化工原料&#xff0c;主要用于锂电池的制造和其他化学合成过程。它对纯度有较高要求&#xff0c;因此在制备和处理过程中&#xff0c;去除杂质如钙镁离子是非常关键的步骤。 关于碳酸锂溶液除钙镁的方法&#xff0c;几种常见的处理技术包括沉淀法、离…

C++ | Leetcode C++题解之第264题丑数II

题目&#xff1a; 题解&#xff1a; class Solution { public:int nthUglyNumber(int n) {vector<int> dp(n 1);dp[1] 1;int p2 1, p3 1, p5 1;for (int i 2; i < n; i) {int num2 dp[p2] * 2, num3 dp[p3] * 3, num5 dp[p5] * 5;dp[i] min(min(num2, num3…

HTML 基础知识

html文档结构 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><title>页面标题</title> </head> <body><!-- 页面内容 --> </body> </html><!DOCTYPE html>声明文…

解决R语言找不到系统库导致的报错

1、基本需知 1.1、系统库 系统库&#xff08;System library&#xff09;是一组预先编写和编译好的软件模块集合&#xff0c;用于支持操作系统的基本功能和提供一些常见的服务。这些库通常由操作系统或第三方开发者提供&#xff0c;并且在系统安装过程中被预装或者用户可以额…

springboot+vue+mybatis高校宿舍管理系统+PPT+论文+讲解+售后

随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于高校宿舍管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了高校宿舍管理系统&#xff0c;它彻底改变了过去传统…

【Linux】从零开始认识多线程 --- 线程互斥

人生有许多事情 正如船后的波纹 总要过后才觉得美的 -- 余光中 线程互斥 1 线程类的封装1.1 框架搭建1.2 线程启动1.3 线程终止1.4 线程等待1.5 运行测试 2 线程互斥2.1 多线程访问的问题2.2 解决办法 --- 锁2.3 从原理角度理解锁 Thanks♪(&#xff65;ω&#xff65;)&am…