C语言——指针进阶(二)

news2025/1/10 2:55:41

目录

七.函数指针数组

八.指向函数指针数组的指针

九.回调函数

结尾


七.函数指针数组

说白了函数指针数组就是函数指针名字后面添加[  ],二者结合成为数组。

那么这个函数指针数组到底有什么用呢?先不用着急,下面用一个计算器功能代码为大家抛砖引玉。

这是一个简单的计算器代码,通过选择不同的功能让其进入不同的函数计算数字。

void menu()
{
	printf("***********************\n");
	printf("*****1.add   2.sub*****\n");
	printf("*****3.mul   4.div*****\n");
	printf("*****0.exit       *****\n");
	printf("***********************\n");
}
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mull(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		
		switch (input)
		{
		case 1:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Add(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Sub(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Mull(x, y);
			printf("%d\n", ret);
			break;

		case 4:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Div(x, y);
			printf("%d\n", ret);
			break;

		case 0:
			printf("退出程序\n");
			break;

		default :
			printf("输入错误,请重新输入:\n");




		}

		
	} while (input);


	return 0;
	
}

但这样我们会发现一个问题,当我们尝试添加更多的函数功能时,switch会变得越来越长,更繁杂了。

通过分析代码可以知道,其实每个函数的功能并不相同,但是它们所使用的形参和所代表的函数类型都是一样的。 

接下来我们来修改一下代码:

先把switch部分删掉,改成函数指针数组。

可以看到这里面的下标与我们计算器的选择对应不上,这时候可以用NULL来占用数组一个位置。

然后通过条件if语句来实现函数功能就行了。

八.指向函数指针数组的指针

感兴趣可以当作扩展了解一下哈~

指向函数指针数组的指针,怎么说呢本质是指针,那存储对象就应该是函数指针数组的地址了。

而我们需要的指针则由(*p)括起来确保是指针而不是数组,这里pfArr简化成p方便辨认。最后就变成了指向这个数组的指针了。重点是指向数组,而不是变成数组。

九.回调函数

我们回到switch代码部分进行回调函数的实现:我们可以先封装一个函数,再让代码相似部分调用4次即可。

这就是回调函数的神奇之处,用函数指针来接受所需要的函数功能,在calc函数里面使用已经接受了功能函数的地址的指针,输入实参。

进一步理解回调函数:

老规矩,先用简单的例子帮助大家理解,后面再深入了解qsort的妙用。先用一个经典例子:冒泡排序。

其实冒泡排序很简单,10个元素该元素最差跑9次交换,n个元素就跑n-1次。每一次跑完下一个元素都会减少一次对比。

其实这个函数不够通用,它只能排序整型。

接下来我们就来介绍qsort函数,这个通用排序函数。

通过这个我们知道两个相同类型数据的比较方法是不同的。

那么可以推出qsort的第四项形参是提供两个数据的比较方法。我们可以想象把上诉冒泡排序中的9和8分别传输给e1,e2,让它们在cmp里面比较。不过这时候会遇到一个问题,*e1会出错,原因在于void*类型是无法进行解引用的。

void*的真正作用是接受各种类型的指针:

所以如果要实现整型比较大小只能先强制转换了。

cmp的规则是当p1指向的元素>p2指向的元素时返回大于0的数字,相等返回0,小于返回小于0的数字。

运行代码,排序成功。其实qsort最关键的部分是第四个形参,必须得创建这个数据对应类型的比较方法才可以进行,比如整型用<>来比较,结构体可以用字符串长度来比较等等。

 

下面我们来测试结构体排序:

又到了最关键的创造比较函数部分。

 

 再尝试按照名字比较,这时候的名字是字符串,可不能用减号来表示结果了,可以用到strcmp这个函数来比较字符串,巧合的是strcmpd的返回类型与cmp的返回规则一致。

 

字符串之间的排序是按照字典顺序比较的,比如abc与aq,一开始两个a相同,但后面的q比b大,所以abc排在aq的前面。

结尾

本文最精彩的一部分就在于qsort排序了,它不同于我们传统的单一类型的排序,它更加多样性,赋予了我们更多排序的思路。

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

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

相关文章

【Linux】——网络基础:http协议

目录 前言 应用层 认识协议 协议的概念 传输结构化数据 序列化和反序列化 网络版本计算器 服务器端Server 客户端Client 协议定制 其它 运行效果 HTTP协议 HTTP的简介 认识URL urlencode和urldecode HTTP协议格式 HTTP请求 HTTP响应 HTTP的方法 GET和POST…

时序分解 | MATLAB实现基于LMD局部均值分解的信号分解分量可视化

时序分解 | MATLAB实现基于LMD局部均值分解的信号分解分量可视化 目录 时序分解 | MATLAB实现基于LMD局部均值分解的信号分解分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 LMD局部均值分解 直接替换Excel即可运行包含频谱图相关系数图 Matlab语言 1.算法新颖…

UMA 2 - Unity Multipurpose Avatar☀️七.UMA API介绍

文章目录 🟥 UMA Data DNA参数引用位置🟥 UMA API介绍🟥 UMA Data DNA参数引用位置 我们想通过代码去控制如图所示参数,达到捏脸的目的.下面就是可以控制的代码: _dna["headSize"].Set(1); _avatar.BuildCharacter();我们观察发现操控代码类似Material去设置…

01_瑞萨GUI(LVGL)移植实战教程之软件和硬件准备

本系列教程配套出有视频教程&#xff0c;观看地址&#xff1a;https://www.bilibili.com/video/BV1gV4y1e7Sg 1. 软件和硬件准备 1.1 本节要点 本节学习如何搭建开发环境&#xff0c;硬件接线&#xff0c;为我们后续的学习做好基础必要的准备。 1.2资料准备 本文档所有用到…

flink 端到端一致性

背景 我们经常会混淆flink提供的状态一致性保证和数据端到端一致性保证的关系&#xff0c;总以为他们表达的是同一个意思&#xff0c;事实上&#xff0c;他们不是一个含义&#xff0c;flink只能保证其维护的内部状态的一致性&#xff0c;而数据端到端的一致性需要数据源&#…

Python下载、安装及如何配置Pycharm(Windows 11)详细教程

本文介绍在Windows 11系统Python的下载、安装及配置Pycharm 一、下载 官网地址&#xff1a;https://www.python.org/downloads/windows/ 1、选择Python 3.10.5版本下载 二、安装 1、选择自定义安装 2、全部默认勾选&#xff0c;点击Next 3、自定义安装路径 建议勾选inst…

il2cpp分析-gobal-metadata.dat解密

gobal-metadata.dat解密 工具:010Editor,IDA 7.5,Jadx,VS Code 样本Last Island of Survival_6.3_Apkpure.xapk 分析Il2cpp文件 打开ida,把libil2cpp拖到ida中按快捷键ShiftF12等待字符串分析完后,搜索global-metadata.dat 双击搜索出来的结果 点击aGlobalMetadata 然后…

【并发编程八股】进程、线程、并发编程三大特性

目录 进程与线程的概念&#xff1f;串行、并行、并发的概念&#xff1f;同步异步、阻塞非阻塞的概念&#xff1f;线程的创建的方式&#xff1f;继承 Thread 类&#xff0c;重写 run 方法实现Runnable接口&#xff0c;重写 run 方法实现Callable&#xff0c;重写 call 方法&…

蚂蚁链发布全新Web3品牌ZAN,涉及RWA、合规等服务

9月8日&#xff0c;在外滩大会见解论坛「从科幻到科技&#xff1a;Web3、元宇宙、AIGC」现场上&#xff0c;蚂蚁集团旗下的蚂蚁链联合Everest Ventures Group、HASHKEY、Morpheus labs发布全新Web3品牌ZAN。原蚂蚁链CTO张辉担任ZAN CEO。 该品牌致力于服务Web3机构客户与Web3应…

【数据结构】学习笔记

文章目录 绪论线性表栈、队列、数组串树与二叉树图查找排序 绪论 线性表 栈、队列、数组 串 树与二叉树 图 查找 排序

2023/9/9总结

nodejs Node.js 是基于chrome的v8引擎封装&#xff0c;独立执行于JavaScript代码的环境 Node.js环境中没有BOM和DOM 作用&#xff1a; 编写后端程序&#xff1a;提供数据和网页资源等 前端工程化&#xff1a;集成各种开发中使用的工具和技术 fs模块--读写文件 模块&#xf…

(LeetCode)两数相加深入分析Java版

两数相加&#xff08;题目如下&#xff09; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数…

华为云云耀云服务器L实例评测 | 开启OPC UA之旅

OPC Unified Architecture (OPC UA)是一种用于工业自动化的M2M协议(Machine-to-machine)&#xff0c;具有平台独立性&#xff0c;在Windows和Linux上都可以运行。随着云服务在工业现场的不断普及&#xff0c;OPCUA服务也开始大量部署在云端。 本文以华为云云耀云服务器L为基础…

Mybatis中动态SQL标签和内置参数介绍

Mybatis中动态SQL标签和内置参数 一、MyBatis动态SQL 1.1、sql标签 sql标签用于抽取公用的SQL代码&#xff0c;定义sql标签的时候需要通过【id】属性设置唯一标识。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-…

CocosCreator3.8研究笔记(十二)CocosCreator 字体资源理解

Cocos Creator 常用的字体资源有三种&#xff1a;系统字体、动态字体、位图字体。 一、系统字体 系统字体是调用运行平台自带的系统字体来渲染文字&#xff0c;不需要用户在项目中添加任何相关资源。 使用系统字体&#xff0c; Label 组件 Use System Font 属性需要勾选。 Fo…

使用Spring Security保障你的Web应用安全

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

用户权限数据转换为用户组列表(3/3) - Excel PY公式

最近Excel圈里的大事情就是微软把PY塞进了Excel单元格&#xff0c;可以作为公式使用&#xff0c;轻松用PY做数据分析。系好安全带&#xff0c;老司机带你玩一把。 实例需求&#xff1a;如下是AD用户的列表,每个用户拥有该应用程序的只读或读写权限&#xff0c;现在需要创建新的…

迅软DSE文档权限管理:实现受限访问,确保重要机密绝不外泄

在现代办公中&#xff0c;文档已经成为信息存储、使用以及流转的重要载体&#xff0c;这些文档在企业内外共享和流转&#xff0c;期间若是谁都可以对其进行访问、复制、删除、截屏、打印……会给企业的信息安全带来许多隐患。 对文档实行差异化管理已经成为企业机密保护一部分&…

智能小车之蓝牙控制并测速小车、wife控制小车、4g控制小车、语音控制小车

目录 1. 蓝牙控制小车 2. 蓝牙控制并测速小车 3. wifi控制测速小车 4. 4g控制小车 5. 语音控制小车 1. 蓝牙控制小车 使用蓝牙模块&#xff0c;串口透传蓝牙模块&#xff0c;又叫做蓝牙串口模块 串口透传技术&#xff1a; 透传即透明传送&#xff0c;是指在数据的传输过…

【数据结构】堆排序和Top-k问题

【数据结构】堆 堆排序 如果只是将待排数组建立一个大堆或者小堆是无法得到一个升序或者降序的数组&#xff0c;因为对与一个堆&#xff0c;我们没法知道同一层的大小关系。 但是&#xff0c;如果建立了一个大堆&#xff0c;那么堆顶元素一定是这个数组中最大的&#xff0c;…