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

news/2024/7/24 10:05:35 标签: c语言, 面试, 开发语言

目录

七.函数指针数组

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

九.回调函数

结尾


七.函数指针数组

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

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

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

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.niftyadmin.cn/n/5015449.html

相关文章

git打tag和版本控制规范

我们在开发中经常会遇到要打tag的情况&#xff0c;但这个tag应该如何打呢&#xff1f;我不知道大家平时是怎么打的&#xff0c;但我基本就是从1.0.0开始进行往上递增&#xff0c;至于如何递增&#xff0c;基本凭感觉。今天同事新打了一个tag进行发版&#xff0c;然后被架构点名…

【css】margin:auot什么情况下失效

margin&#xff1a;auto只对块级元素有效果&#xff0c;并且在正常文档流margin&#xff1a;automargin&#xff1a;0 auto&#xff0c;css默认在正常文档流里面margin-top和margin-bottom是0 为什么margin: auto能实现水平居中&#xff0c;而垂直居中不行&#xff1f; 一般子…

Arrays.copyOf 和System.arraycopy?深拷贝和浅拷贝?

Arrays.copyOf 和 System.arraycopy 1&#xff09;二者有何不同&#xff1f; System.arraycopy()方法 System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length); 需主动创建目标对象dest可定义起始元素&#xff0c;灵活拷贝元素比较重要的一点&…

春秋云镜 CVE-2016-0785

春秋云镜 CVE-2016-0785 S2-029 靶标介绍 2.3.28 之前的 Apache Struts 2.x 允许远程攻击者通过标签属性中的“%{}”序列执行任意代码。 启动场景 漏洞利用 工具利用 得到flag flag{a4c7fc9a-8e2d-49b8-9b09-22790fb2bfb6}

第17节-PhotoShop基础课程-画笔修复工具

文章目录 前言1.画笔工具1.基本操作2.工具选项1.不透明度2.流量3.平滑2.画笔大小工具栏大小设置 4.笔刷 2.铅笔工具3.颜色替换工具 批量替换颜色4.混合器画笔工具-人像精修 前言 画笔工具的使用 1.画笔工具 1.基本操作 画画 2.工具选项 1.不透明度 2.流量 设置低了会有间隔&…

我的中控考勤机操作类

请注意 上传图片的方法 public class ZhongkongCamGets{public bool bIsConnected false; public zkemkeeper.CZKEMClass axCZKEM1 new zkemkeeper.CZKEMClass();private int iMachineNumber 1;private MZhongkongInfo ZhongkongModel;public ZhongkongCamGets(MZhongkongI…

Spring Boot与Kubernetes:现代云部署的完美组合

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

Python 图片处理

Step1 提取PDF中的图片&#xff0c;并另存 Step2 去除灰色纸张背景 import PyPDF2 from PIL import ImageEnhance,Image,ImageFilter import cv2 import numpy as np from skimage.filters import unsharp_mask from skimage.filters import gaussian from skimage.restora…