浅学指针(4)函数指针数组和qsort的使用

系列文章目录

文章目录

  • 系列文章目录
  • 前言
  • 1.函数指针数组的⽤途
    • 作用:可以让代码更简洁,逻辑更清晰
  • 2. 回调函数
    • 回调函数就是⼀个通过函数指针调⽤的函数
  • 3 . qsort函数
    • qsort函数可以排序所有数据类型
    • 解释如图:![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a3eca975d2f1467db785660acf7e0209.png) 比较函数是用函数指针接收,内部实现后面我还会讲
    • 3. 1使⽤qsort排序结构体数据
  • 5 ..qsort函数的模拟实现
    • 补充:qsort可以排所有的数据类型,下面写的代码是qsort内部实现


前言

掌握函数指针数组的使用,qsort函数的实现。

1.函数指针数组的⽤途

作用:可以让代码更简洁,逻辑更清晰

计算机的实现:
简单的加减法运算
代码1

#include <stdio.h>
int add(int a, int b)//加法
{return a + b;
}
int sub(int a, int b)//减法
{return a - b;
}
int main()
{int x, y;int input = 1;int ret = 0;do{printf("*************************\n");printf(" 1:add 			   2:sub \n");printf(" 0:exit 				 \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;default:printf("选择错误\n");break;}} while (input);return 0;
}

在这里插入图片描述
这个时候就可以用函数指针数组了,
改造:
代码2

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
void calc(int(*pf)(int, int))
{int ret = 0;int x, y;printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}
int main()
{int x, y;int input = 1;int ret = 0;int(*p[3])(int x, int y) = { 0, add, sub }; //转移表do{printf("*************************\n");printf(" 1:add 			   2:sub \n");printf(" 0:exit 				 \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);if ((input <= 4 && input >= 1)){printf( "输⼊操作数:" );scanf( "%d %d", &x, &y);ret = (*p[input])(x, y);printf( "ret = %d\n", ret);}else if(input == 0){printf("退出计算器\n");}else{printf( "输⼊有误\n" ); }return 0;
}

看这样子是不是很简洁,那么是怎么调用的呢?

int(*p[3])(int x, int y) = { 0, add, sub };

如图:
在这里插入图片描述

2. 回调函数

回调函数就是⼀个通过函数指针调⽤的函数

如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。
回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。上面代码1中我们写的计算机的实现的代码中,红⾊框中的代码是重复出现的,其中虽然执⾏计算的逻辑是区别的,但是输⼊输出操作是冗余的,有没有办法,简化⼀些呢?
因为红⾊框中的代码,只有调⽤函数的逻辑是有差异的,我们可以把调⽤的函数的地址以参数的形式传递过去,使⽤函数指针接收,函数指针指向什么函数就调⽤什么数,这⾥其实使⽤的就是回调函数的功能。

3 . qsort函数

qsort函数可以排序所有数据类型

传参必要参数:
在这里插入图片描述
那她是怎么实现的呢?
代码3:

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数
int int_cmp(const void * p1, const void * p2)
{return (*( int *)p1 - *(int *) p2);
}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), 	int_cmp);for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++){printf( "%d ", arr[i]);}printf("\n");return 0;
}

解释如图:在这里插入图片描述
比较函数是用函数指针接收,内部实现后面我还会讲

3. 1使⽤qsort排序结构体数据

可以按名字,也可以按年龄
代码4:

struct Stu //学⽣
{char name[20];//名字int age;//年龄};
//假设按照年龄来⽐较
int cmp_stu_by_age(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的
//假设按照名字来⽐较
int cmp_stu_by_name(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//按照年龄来排序
void test2()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
//按照名字来排序
void test3()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{test2();test3();return 0;
}

其中代码解释,如图:
在这里插入图片描述

5 …qsort函数的模拟实现

使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。

补充:qsort可以排所有的数据类型,下面写的代码是qsort内部实现

注意:这⾥第⼀次使⽤ void* 的指针,讲解 void* 的作⽤。

#include<stdio.h>
int int_cmp(const void * p1, const void * p2)//比较函数跟qsort函数的比较函数一样
{return (*( int *)p1 - *(int *) p2);
}
void _swap(void *p1, void * p2, int size)
{int i = 0;for (i = 0; i< size; i++)//因为不知道数据类型(void)所以两个元素选择一个一个字节交换{char tmp = *((char *)p1 + i);*(( char *)p1 + i) = *((char *) p2 + i);*(( char *)p2 + i) = tmp;}
}
void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{int i = 0;int j = 0;for (i = 0; i< count - 1; i++){for (j = 0; j<count-i-1; j++){//和冒泡相似if (cmp ((char *) base + j*size , (char *)base + (j + 1)*size) > 0)//cmp函数返回值是int,判断>0,如果成立,执行语句{_swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);//size是宽度,不知道}}}}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)//打印{printf( "%d ", arr[i]);}printf("\n");return 0;
}

解析:在上面代码注释里,还有if语句代码的解释,如图:
在这里插入图片描述
好了,这就是今天所有的内容啦!宝子们都看到这里了,点一个赞,谢谢,下期再见.

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

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

相关文章

Google Chrome 下载 (离线版)

1 访问网址 Google Chrome 网络浏览器 2 点击 下载Chrome 3 直接运行 ChromeStandaloneSetup64.exe 其他&#xff1a; ####################### 谷歌浏览器 (Google Chrome) 最新版离线安装包下载 https://www.iplaysoft.com/tools/chrome/#google_vignette Google Chrome …

socks5代理如何工作?socks5代理可以用来做什么?

socks5代理是一种网络代理服务器&#xff0c;它通常用于改变网络请求的传输方式和地址&#xff0c;从而使得网络请求能够通过代理服务器进行访问。本文将介绍socks5代理的工作原理、优势、使用场景以及如何选择合适的socks5代理。 一、socks5代理的工作原理 socks5代理是一种协…

一文读懂设备巡检的主要内容

在现代企业和组织中&#xff0c;设备的正常运行是业务持续发展的关键&#xff0c;尤其是制造业&#xff0c;由于其发展趋势不断机械化、自动化、大型化、高速化和复杂化&#xff0c;对设备巡检的要求越来越高。然而&#xff0c;在信息化时代&#xff0c;很多企业目前仍采用纸笔…

GPT实战系列-大模型训练和预测,如何加速、降低显存

GPT实战系列-大模型训练和预测&#xff0c;如何加速、降低显存 不做特别处理&#xff0c;深度学习默认参数精度为浮点32位精度&#xff08;FP32&#xff09;。大模型参数庞大&#xff0c;10-1000B级别&#xff0c;如果不注意优化&#xff0c;既耗费大量的显卡资源&#xff0c;…

Python应用:利用matplotlib画学生成绩分布饼图

1. 题目 给定一组学生成绩&#xff1a;[85, 92, 78, 65, 95, 88, 72, 60, 98, 45, 100, 46, 23, 88, 67, 89, 67, 88, 99]&#xff0c;现在评分等级为优&#xff08;90-100&#xff09;、良&#xff08;70-89&#xff09;、及格&#xff08;60-69&#xff09;、不及格&#xff…

玩转大数据4:大数据的崛起与应用领域探索

图片来源网络 引言 在当今数字化时代&#xff0c;大数据正以前所未有的速度和规模崛起。大数据的出现不仅改变了企业和组织的经营模式&#xff0c;也对我们的社会生活带来了深刻的影响。Java作为一种广泛使用的编程语言&#xff0c;在大数据领域发挥着重要的作用。本文将重点…

工程师每日刷题 -4

文章目录 1、深度学习2、算法与数据结构2.1、暴力解法2.2、滑动窗口法 3、编程基础 1、深度学习 问题&#xff1a;CNN的本质和优势&#xff1f; CNN 本质上是一个多层感知机 (MLP)&#xff0c;其成功的原因关键在于它所采用的【稀疏连接】&#xff08;局部感受&#xff09;和…

【带头学C++】----- 九、类和对象 ---- 9.3 析构函数

9.3 析构函数 9.3.1 如何定义析构函数 函数名和类名称相同&#xff0c;在函数名前加 ~ &#xff0c;没有返回值类型&#xff0c;没有函数形参。 (不能被重载) 当对象生命周期结束的时候&#xff0c;系统自动调用析构函数&#xff08;析构函数会先清理对象占用内存空间存放的…

【openssl】Window系统如何编译openssl

本文主要记录如何编译出windows版本的openss的lib库 1.下载openssl&#xff0c;获得openssl-master.zip。 a.可以通过github&#xff08;网址在下方&#xff09;上下载最新的代码、今天是2023.12.1我用的master版本&#xff0c;下载之后恭喜大侠获得《openssl-master.zip》 …

快递物流模拟系统

快递物流模拟系统 文章目录 快递物流模拟系统一、目的二、技术实现&#xff1a;三、网页功能具体介绍 一、目的 调用百度地图 JavaScript API 创建的简单的基站物流GPS定位与监控系统的示例网页 二、技术实现&#xff1a; 使用百度地图 JavaScript API 版本 2.0。利用 BMap …

Webpack——Webpack简介

1、什么是Webpack&#xff1f; Webpack是一个开源的JavaScript模块打包工具&#xff0c;其最核心的功能是解决模块之间的依赖&#xff0c;把各个模块按照特定的规则和顺序组织在一起&#xff0c;最终合并为一个JS文件&#xff08;有时会有多个&#xff0c;这里讨论的只是最基本…

SQL Sever 基础知识 - 数据排序

SQL Sever 基础知识 - 二 、数据排序 二 、对数据进行排序第1节 ORDER BY 子句简介第2节 ORDER BY 子句示例2.1 按一列升序对结果集进行排序2.2 按一列降序对结果集进行排序2.3 按多列对结果集排序2.4 按多列对结果集不同排序2.5 按不在选择列表中的列对结果集进行排序2.6 按表…

人才缺口达150万!云计算凭什么这么火?

《中国互联网发展报告2022》指出&#xff0c;2021年&#xff0c;我国云计算市场规模达到3229亿元&#xff0c;增速为54.4%。未来5年内&#xff0c;我国云计算产业将面临高达近150万的人才缺口&#xff0c;预计未来市场仍将保持30%的增速。与此同时&#xff0c;随着大数据、人工…

【每日OJ —— KY11 二叉树遍历】

每日OJ —— KY11 二叉树遍历 1.题目&#xff1a;KY11 二叉树遍历2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目&#xff1a;KY11 二叉树遍历 2.解法 2.1.算法讲解 1.首先需要创建二叉树结构。 2.其次&#xff0c;根据题目根据题目遍历的顺序要求来实现构建二叉树的…

代码demo-内部订单批量投料

为了简化用户操作&#xff0c;开发内部订单批量投料功能 用户可以批量上传&#xff0c;或者选择对应的物料&#xff0c;输入库位和内部订单号后进行过账操作 对用户选择的内部订单做校验&#xff0c;内部订单是否正确 内部订单的公司是否和工厂对应的公司一致等等 下面展示…

Sui与阿联酋科技孵化器Hub71合作支持生态项目建设,扩大全球影响力

近日&#xff0c;总部位于阿联酋&#xff08; United Arab Emirates &#xff0c;UAE&#xff09;的科技孵化器Hub71宣布与Mysten Labs合作&#xff0c;将支持Sui上的新项目。通过本次合作&#xff0c;孵化项目的开发者们不仅可以获得Mysten Labs的技术专业知识和支持&#xff…

Flutter基础开发

参考:http://bbs.itying.com/topic/5cdb83b7fac8b00944a7a0c3 参考:https://www.bilibili.com/video/BV1S4411E7LY?p34&spm_id_frompageDriver 1.使用镜像 由于在国内访问Flutter有时可能会受到限制&#xff0c;Flutter官方为中国开发者搭建了临时镜像&#xff0c;大家可以…

SpringBoot整合MyBatis-Plus

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

【HTTP协议】简述HTTP协议的概念和特点

&#x1f38a;专栏【网络编程】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出小吉的问题 文章目录 &#x1f33a;概念&#x1f33a;特点&#x1f384;请求协议&#x1f384;响应协议…

java第二十六课

数据库多表 多表做到每个表的字段名称不一样 Mysql 关系数据库 结合到商城&#xff1a;用户表 订单表 商品表 商品详情表 用户表:字段&#xff1a; 用户 id:唯一标志用户 用户名称&#xff1a;name 用户性别&#xff1a;sex 用户年龄:age 用户地址&#xff1a;position 用户密码…