c语言指针进阶(二)

news2024/11/25 14:42:03

目录

引言

函数指针数组

指向函数指针数组的指针

回调函数


引言

        大家好,我是c语言boom成家宝,今天博主带来的依然是指针的进阶讲解。上一篇博客博主有介绍指针,数组指针,指针数组,以及函数指针的概念以及应用,对此还不太了解的小伙伴请移步上一篇,链接:http://t.csdn.cn/eW2yg

函数指针数组

        上一篇博客有提到函数指针的使用,那么函数指针数组呢顾名思义就是数组每个元素都是函数指针的类型,就叫做函数指针函数。那么指针函数数组到底可以怎么使用呢?请看以下代码:


#define _CRT_SECURE_NO_WARNINGS 1 
#include <stdio.h>

//用函数指针简单实现计算器功能的一个代码

int  add(int x, int y) {
	//加法
	return (x + y);
}
int  sub(int x, int y) {
	//减法
	return (x - y);
}
int  mul(int x, int y) {
	//乘法
	return (x * y);
}
int  div(int x, int y) {
	//除法
	return (x / y);
}

int main() {
	int (*p1)(int, int) = add; //函数指针
	int (*p2)(int, int) = sub;
	int (*p3)(int, int) = mul;
	int (*p4)(int, int) = div;
	return 0;
}

        代码思路很简单,就是main函数里使用的函数指针的一个计算机加减乘除的代码展示。但是仔细研究又觉得代码重复部分实在太多,这些代码从主函数到加减乘除四个函数的逻辑和代码格式基本都是相同的,那我能不能把他们直接放在一起,等具体需要什么就可以直接调用什么呢?答案是:当然可以啦。比如我们今天讲解的-----函数指针数组。我们可以在main函数里这样写:


int main() {
	//int (*p1)(int, int) = add; //函数指针
	//int (*p2)(int, int) = sub;
	//int (*p3)(int, int) = mul;
	//int (*p4)(int, int) = div;

	int (*parr[4])(int, int) = { add,sub,mul,div };//函数指针数组
	return 0;

        有些小伙伴可能就想说,这样看来没发现函数指针数组有多省功夫啊。那我们不妨把这个简易的计算器功能完全实现出来。相信大家能够看出来上述代码只是实现了计算器的逻辑,还没有传值给它并且把计算结果打印等。那如果我们不使用函数指针数组,实现它的方法只有switch语句,一种情况对应一种计算功能。并且每一种功能都得传值,然后调用函数,再打印结果,实在重复。而且真正的计算器功能肯定也不只有加减乘除四个功能。一直switch下去要写多久?十分冗余!大概代码参照如下图。

 

 

所以博主对函数指针数组的方法进行讲解一下。代码如下:


#define _CRT_SECURE_NO_WARNINGS 1 
#include <stdio.h>
int  add(int x, int y) {
	//加法
	return (x + y);
}
int  sub(int x, int y) {
	//减法
	return (x - y);
}
int  mul(int x, int y) {
	//乘法
	return (x * y);
}
int  div(int x, int y) {
	//除法
	return (x / y);
}
void menu() {
	//简易菜单,相应选择就进行相应逻辑
	printf("**********************\n");
	printf("*****1.add****2.sub***\n");
	printf("*****3.mul****3.div***\n");
	printf("**********************\n");
}
int main(){
	menu();
	int (*parr[5])(int, int) = { NULL,add,sub,mul,div };//函数指针数组的创建
	int x, y;
	scanf("%d,%d", &x, &y);//接受两个整数进行计算
	int input = 0;
	int ret;
	do {
		
		menu();
		printf("请选择%d", input);
		ret = parr[input](x, y);//函数指针数组的应用
		printf("%d", ret);//结果
	
	} while (input);

	return 0;
}

        通过这样的方式我们就可以直接调用自己需要的功能了。如果后续又开发出了新的函数功能,我们只需要添加即可,较传统的switch语句添加就更方便,也更简洁。

指向函数指针数组的指针

        

int(*p)(int,int)//函数指针
int(*parr[])(int ,int) //函数指针数组
int(*(*p)[])(int,int)=&parr;//&parr函数指针数组的地址,
                             //p就是指向函数指针数组的指针

        当然,这个可以无限套娃一直套下去,因为有地址就有指针,有指针就又有地址。不过基本到这里就已经够用了,再深入套下去也没有意义,也基本没有实用场景,代码可读性也不高。

回调函数

        回调函数是一个通过函数指针调用的函数。如果你把函数指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由函数的实现方直接调用,而是特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

        比如我们还是上述最开始那个冗余的代码。除了使用函数指针数组来解决冗余的问题以外,我们还可以使用回调函数来解决。我们把switch语句里的内容改成这样:

         然后声明Calc()函数,

 代码逻辑如下图:简单明了,相信大家自行都能 看懂,博主就是提供一种回调的思想。

回调函数的用处很大,例如c语言中一个经典的库函数qsort,快速排序,就是利用的这个回调的思想。具体快速跑徐是怎么实现的呢博主就留到下一次的博客单独讲解。

 

 

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

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

相关文章

【Azure】Azure成本管理:规划、监控、计算和优化成本 [文末送书]

开篇先来一个不是总结的总结&#xff1a;平衡成本与性能始终是一个重大挑战。&#xff08;此处省略各种场景的解释&#xff09; 文章目录 前言一、Azure 成本管理工具1.1 什么是成本管理1.2 成本管理的主要功能 二、Azure 中可能影响成本的因素2.1 影响成本的因素2.1.1 资源类型…

leetcode|math|9.172.69.50.

9. Palindrome Number to_string 就行 172. Factorial Trailing Zeroes 不能直接乘起来&#xff0c;会overflow&#xff01;&#xff01; 166! 就是要找166乘到1一共有几个5。5&#xff0c;10&#xff0c;15&#xff0c;25...都算。166/5就是算一共有几个5。但是25其实贡献了…

【周末闲谈】感受AI时代魅力,创意无界限

i 个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 文章目录 前言人工智能的应用领域问题求解逻辑推理与定理证明自然语言处理智能信息检索技术专家系统 人工智能的三大短板展望未来从专用智能向通用智能发展从人工智能向人机混合智能发展…

Jdk 版本升级

Jdk 版本升级(多版本配置&#xff09; 一、配置多版本 首先如果系统第一次安装JDK 1.登录oracle官网Java Downloads | Oracle下载&#xff0c;此教程以Jdk1.8为例&#xff0c;一键下一步即可安装成功。 2.配置环境变量 然后在系统path路径中添加&#xff1a; %JAVA_HOME%…

单片机第一季:零基础10——串口通信和RS485

目录 1&#xff0c;串口通讯基础 1.1&#xff0c;同步和异步 1.2&#xff0c;并行和串行 1.3&#xff0c;单工、半双工与全双工通信 1.4&#xff0c;通信速率 2&#xff0c;单片机串口通讯 2.1&#xff0c;接口标准 2.2&#xff0c;通讯协议 2.3&#xff0c;串口…

834. 树中距离之和

给定一个无向、连通的树。树中有 n 个标记为 0…n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges &#xff0c; edges[i] [ai, bi]表示树中的节点 ai 和 bi 之间有一条边。 返回长度为 n 的数组 answer &#xff0c;其中 answer[i] 是树中第 i 个节点与所有其他节点之间…

opencv环境搭建

1. 上网&#xff08;你懂的&#xff0c;没有网装不了&#xff09; 2. 参考视频&#xff1a;https://www.bilibili.com/video/BV1R44y157hW/?spm_id_from333.880.my_history.page.click&vd_source377867a48dd3d812b9d6521c8fc76de2 3. 这里我选择的是4.8的版本。 4. cmak…

charles中下载web证书

1.点击help&#xff0c;选中ssl Proxying ,点击Install Charles Root Certificate 2:点击”安装证书”按钮 3&#xff1a;点击”下一步”按钮 4&#xff1a;选中”将所有的证书都放入下列存储”&#xff0c;点击”游览”按钮 5&#xff1a;选中”受新任的根证书颁发机构”&…

day37-框架

0目录 框架 1.框架介绍 2. SSM三大框架简介 3.Mybatis 4.拓展 1.框架介绍 1.1 为什么使用框架&#xff1f; &#xff08;1&#xff09;框架效率高&#xff0c;成本低 &#xff08;2&#xff09;框架是别人写好的构建&#xff0c;我们只需学会如何使用它&#xff08;可维护性…

C++(12):动态内存

除了自动和static对象外&#xff0c;C还支持动态分配对象。动态分配的对象的生存期与它们在哪里创建是无关的&#xff0c;只有当显式地被释放时&#xff0c;这些对象才会销毁。 静态内存 用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量。 栈内存 用来…

mysql_to_clickhouse同步方案调研

调研时间&#xff1a;2021年08月&#xff0c;之后是否出现优化方案未知 方式1&#xff1a;网上开源python脚本-----mysql-clickhouse-replication 安装参考&#xff1a;https://www.cnblogs.com/gomysql/p/11199856.html 软件路径&#xff1a;https://github.com/yymysql/my…

【C++STL】模拟实现vector容器

文章目录 前言一、vector的成员函数二、增删查改工作说明size()和capapcity()2.1reserve()2.2 resize&#xff08;&#xff09;2.3 insert()2.4 erase&#xff08;&#xff09;2.5 push_back&#xff08;&#xff09;和pop_back&#xff08;&#xff09; 三、[]重载和迭代器3.1…

ahut 周赛3

A.gzm判试卷 AhutOj 线段树(注意,一定要开到4*N,不然会RE) 单点更新(求区间最值) 单点更新不需要懒标记,区间修改是大量的点,需要懒标记 AC代码: #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace st…

Jmeter接口测试从0到1打通,从安装到接口测试实例(超细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、Jmeter简介 J…

安装adobe系列产品,提示错误代码81解决办法

安装adobe系列软件&#xff0c;如Photoshop、Premiere Pro、Illustrator等时&#xff0c;出现如下图提示错误代码81&#xff0c;如何解决呢&#xff1f;一起来看看。 解决方法一 (重启电脑等待5分钟再安装&#xff01;) 解决方法二 应用程序中打开Adobe Creative Cloud 点击…

分布式文件系统与HDFS的shell操作及查看元数据

启动hadoop和hive的metastore查看sbin的目录下的文件 执行./start-all.sh 查看相关的进程

node.js重装问题

目录 问题一&#xff1a; 问题二&#xff1a; node.js安装分享&#xff1a; node.js重装参考&#xff1a; 问题一&#xff1a; 使用&#xff08;npm install express -g&#xff09;报错&#xff1a; config global --global -local are deprecated. Use --locationglobal …

【软件测试】Window与Linux系统下-初始化Git环境(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Window 初始化 Gi…

python开发ESP32之环境配置(一)

1、开发编辑器 Thonny 2、串口驱动安装 通过type-c线将芯片链接电脑&#xff0c; 右击我的点电脑——管理——设备管理器&#xff0c;查看驱动安装是否正常。 异常情况下需要安装驱动&#xff08;CP2102USBQD),根据个人电脑配置选择相应的驱动程序 安装失败的话&…

AcWing1536. 均分纸牌 AcWing122. 糖果传递—数学推导、贪心

均分纸牌 && 糖果传递 均分纸牌糖果传递 均分纸牌 题目链接 AcWing1536. 均分纸牌 问题描述 分析 这道题有个特殊的地方就是A1只能从A2获取纸牌&#xff0c;或者A1只能将多余的纸牌给A2&#xff0c;此操作后A1的纸牌数应该为avg。 A2的纸牌只能从A3获取&#xff0c;…