指针中的回调函数与qsort的深度理解与模拟

  

今天给大家在更新一下指针类型的知识,这里讲到了一个库函数sqort,以及回调函数的理解。

望喜欢

目录

回调函数

qsort函数

qsort模拟实现


回调函数

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

其实我们之前也讲过一点有关这点的内容,那么今天就更详细的来讲解一下,下面我们先看一下两段代码

我们先写出加减乘除的各个函数,用来做一个简单计算器的基本函数。

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a / b;
}

那么我们下面就写一个我们没有使用回调函数来实现的简洁计算器 :

int main()
{int x, y;int input = 1;int ret = 0;do{printf("******************");printf(" 1:add ");printf(" 3:mul ");printf("******************");printf("请选择:");scanf("%d", &input);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;case 3:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

 我们是否一眼就看出里面的重复部分(scanf x ,y  和打印结果的过程)比较多,我们是否能想出一个办法来解决这个问题,竟然我们要讲到回调函数了那么我们的解决方法就是我们要说的回调函数了,下面我就来讲讲如何·使用回调函数来实现简便。

注:这里简化的方法不仅可以用回调函数来实现,还可以使用转移表的方法来实现即函数指针数组来完成。


那么我们再来看一下经过使用回调函数的方法来进行化简的代码:

int main()
{int input = 1;do{printf("******************");printf(" 1:add ");printf(" 3:mul ");printf("******************");printf("请选择:");scanf("%d", &input);switch (input){case 1:calc(add);break;case 2:calc(sub);break;case 3:calc(mul);break;case 4:calc(div);break;case 0:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

那我们仔细对比就会发现哦我们这里多了一个我们不知道的函数,就是calc 函数 那么这便是回调函数,大家可以看到我们在输入想使用的计算方法后,我们都会向回调函数传进去一个相应计算方法的指针,那么这时我们就会再回调函数中通过对应的指针调用这个计算方法的函数。

 讲了那么多那么我们看看我们这里的回调函数的代码是怎么样的: 

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);
}

这里难点在于函数指针即pf,我们这里的形参就是一个函数指针 pf。然后就是根据传进来的函数指针调用计算函数。

这便是回调函数的理解与解析了。


qsort函数

我们看一下cplusplus的解析:

我们现在借助一下图来理解此函数:

 

相信图解已经可以大概理解这个函数了,那么下面我们来用它实现一下冒泡排序的函数:

int cmp_int(void* p1, void* p2)
{return *(int*)p1 - *(int*)p2;}void print(int* p1,int sum)
{for (int i = 0; i < sum; i++){printf("%d ", p1[i]);}}int main()
{int arr[10] = { 11,2,3,4,66,34,13,15,16,10 };qsort(arr, 10, sizeof(arr[1]), cmp_int);print(arr, 10);return 0;
}

们先定义一个cmp_int函数然后按照上图进行传参就可以正常运行了。

大家通过运行结果截图 就可以看到,代码就已经可以完美的运行成功了,完成了排序了。这里我


qsort模拟实现

那么为了更好的理解qsort函数那么接下来我们来模拟实现一下qsort函数:

int cmp_int(void* p1, void* p2)
{return *(int*)p1 - *(int*)p2;}void print(int* p1,int sum)
{for (int i = 0; i < sum; i++){printf("%d ", p1[i]);}}void swap(char* p1, char* p2, size_t with)
{for (int i = 0; i < with; i++){char tem = *p1;*p1 = *p2;*p2 = tem;p1++;p2++;}}void Subble_sort(void* base, size_t sz, size_t with, int (*cmp)(void* p1, void* p2))
{int i, j;for (i = 0; i < sz - 1; i++){for (j = 0; j < sz - 1 - i; j++){if (cmp((char*)base + j * with, (char*)base + (j + 1) * with) > 0){swap((char*)base + j * with, (char*)base + (j + 1) * with, with);}}}}int main()
{int arr[10] = { 11,2,3,4,66,34,13,15,16,10 };Subble_sort(arr, 10, sizeof(arr[1]), cmp_int);print(arr, 10);return 0;
}

代码解析:

这里我们模拟实现的代码中我们仔细一想其实冒泡的趟数是不变的 ,所以冒泡的趟数代码我们就不修改这里的代码了,那么我们要改动的就是比较函数,因为在传进来的数据中不一定是都是整形数组,也可能是字符串数组或结构体数组,我们都需要对此进行改变一下比较函数。这里的交换函数其实我们不需要 不断根据数组类型而改变,因为我们这里是一个一个字节的对两个元素进行交换,只要我们知道元素类型的大小那么我们就可以进行交换任何类型的数组元素。

 

这里函数用整形数据是成功运行的,其他类型的数组就不进行尝试了,在这之前我也尝试过了。


文章已到末尾,望喜欢。

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

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

相关文章

scrapy分布式爬虫的部署,调度,与管理(scrapy + scrapy-redis + scrapyd + gerapy)

使用到的框架及软件包介绍 Github Gerapy 提供主机管理,爬虫项目管理,爬虫任务管理的web管理后台。Github Scrapy-redis 提供中心化的任务队列,任务指纹队列,供分布式爬虫共享爬取任务队列。Github Scrapyd 提供通过api方式单机部署爬虫的功能,爬虫状态查询等。Github Scr…

Mac清理电脑垃圾工具CleanMyMac X4.15中文免费版下载

嘿&#xff0c;亲爱的Mac用户们&#xff0c;你们是否曾经想象过你的电脑是一座美丽的城市&#xff0c;而垃圾文件则是那些不速之客&#xff0c;悄悄堆积&#xff0c;影响着城市的整体美观。今天&#xff0c;我们就来聊聊Mac为什么会产生垃圾文件&#xff0c;这些垃圾文件会对你…

【科研基础】插图摘录

FedSL: Federated Split Learning for Collaborative Healthcare Analytics on Resource-Constrained Wearable IoMT Devices Blockchain-Based Trustworthy and Efficient Hierarchical Federated Learning for UAV-Enabled IoT Networks

01.24 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招&#xff5c;2024届博世中国春季校园招聘&#xff08;内推&#xff09; 校招&#xff5c;2024届博世中国春季校园招聘&#xff08;内推&#xff09; 2、校招&社招&#xff5c;…

蓝桥集训之空调

蓝桥集训之空调 核心思想&#xff1a;差分 目标将t[i]数组变为s[i]数组求出两数组差值 构成新数组w[i]求出w[i]的差分数组 差分的操作:1.左-1 右1 2.单纯-1 3.单纯1 因此求出差分数组后 次数即为将所有数变为0res max(正数之和&#xff0c;负数之和**(绝对值)**) #include…

机械五要素手持气象站的应用

TH-SQ5在数字化和智能化的时代背景下&#xff0c;气象监测技术正日益成为众多行业不可或缺的利器。其中&#xff0c;机械五要素手持气象站以其便携性、实时性和多功能性受到了广泛关注。下面讲解一下手持气象站是什么以及应用&#xff1a; 一、机械五要素手持气象站概述 机械五…

白酒:制曲工艺的环境因素与微生物生态关系

在豪迈白酒的酿造过程中&#xff0c;制曲工艺是非常关键的一环。而环境因素与微生物生态关系对于制曲工艺的成功与否起着决定性的作用。云仓酒庄深谙此道&#xff0c;在制曲过程中注重环境因素的调控&#xff0c;并深入研究微生物生态关系&#xff0c;以提升豪迈白酒的品质和风…

【Java EE 】认识文件与Java文件操作

目录 &#x1f340;认识文件&#x1f338;树型结构组织 和 目录&#x1f338;文件路径&#xff08;Path&#xff09;&#x1f338;其他知识 &#x1f333;Java 中操作文件&#x1f338;File 概述&#x1f33b;属性&#x1f33b;构造方法&#x1f33b;方法 &#x1f338;代码示例…

【论文精读】I-JEPA

摘要 计算机视觉中&#xff0c;常采用基于不变性和基于生成的方法进行自监督学习。对比学习&#xff08;CL&#xff09;是典型的基于不变性的方法&#xff0c;通过预训练方法优化编码器&#xff0c;使其能生成同一图像的两个或多个视图的相似嵌入&#xff0c;其中图像视图通常由…

【Linux实践室】Linux常用命令

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux文件操作2.1.1 &#x1f47b;创建文件2…

【vue.js】文档解读【day 1】 | 模板语法2

如果阅读有疑问的话&#xff0c;欢迎评论或私信&#xff01;&#xff01; 本人会很热心的阐述自己的想法&#xff01;谢谢&#xff01;&#xff01;&#xff01; 文章目录 模板语法JavaScript表达式仅支持表达式调用函数&#xff1f;受限的全局访问 指令参数动态参数动态参数中…

mysql将列默认值设置为uuid

使用mysql版本为8.1.0 建表时设置 create table test(uuid varchar(100) NOT NULL default (uuid()) ,aaaa varchar(100) not null default (uuid()) ,primary key(uuid) );可以看到主键和普通列都可以设置&#xff0c;但是要注意uuid()要加上括号&#xff0c;否则会报错 修…

面试题HTML+CSS+网络+浏览器篇

文章目录 Css预处理sass less是什么&#xff1f;为什么使用他们怎么转换 less 为 css&#xff1f;重绘和回流是什么http 是什么&#xff1f;有什么特点HTTP 协议和 HTTPS 区别什么是 CSRF 攻击HTML5 新增的内容有哪些Css3 新增的特性flex VS grid清除浮动的方式有哪些&#xff…

Yolov8改进交流

YOLO v8改进 YOLOv8的改进&#xff0c;我接触的主要分为网络改进和代码改进&#xff0c;网络改进就是以注意力、主干为主&#xff0c;代码改进就是类似于Iou&#xff0c;类别权重等修改。 以下是yolov8的原始模型。 # Ultralytics YOLO &#x1f680;, AGPL-3.0 license # YO…

Tensorflow2.0+部署(tensorflow/serving)过程备忘记录Windows

Tensorflow2.0部署&#xff08;tensorflow/serving&#xff09;过程备忘记录 部署思路&#xff1a;采用Tensorflow自带的serving进模型部署&#xff0c;采用容器docker 1.首先安装docker 下载地址&#xff08;下载windows版本&#xff09;&#xff1a;https://desktop.docke…

android开发基础自学,Android开发学习视频

谈起性能优化&#xff0c;我想问&#xff0c; 什么是性能优化&#xff1f;你的理解呢&#xff1f; **首先什么是性能&#xff1a;**在同一个手机里面&#xff0c;同样功能的app&#xff0c;哪个跑的快&#xff0c;哪个不卡&#xff0c;哪个就性能高。我们这篇文章就是解决那些…

MEMGPT

1、因为安装环境时是使用的pip install pymemgpt&#xff0c;所以当使用memgpt run运行时&#xff0c;实际上运行的是/home/ubuntu/anaconda3/lib/python3.9/site-packages/memgpt环境目录中的代码。如果想要修改代码&#xff0c;也要在上述目录的文件中修改代码&#xff0c;才…

MacOS 退出默认conda环境

默认关闭 conda config --set auto_activate_base false 将false 改为true 默认打开 近推出当前环境 conda deactivate

[译]BNF 表示法:深入了解 Python 的语法

[译]BNF 表示法&#xff1a;深入了解 Python 的语法 原文&#xff1a;《BNF Notation: Dive Deeper Into Python’s Grammar》 https://realpython.com/python-bnf-notation/ 在阅读Python文档的时候&#xff0c;你可能已经遇到过BNF(Backus–Naur form)表示法&#xff1a; 下…

自动化测试摸索:python+selenium+pytest(持续更新.....)

一、环境搭建 1、python 安装 下载链接&#xff1a;Python Releases for Windows | Python.org 自己选择合适的版本下载 当下载完毕时&#xff0c;找到该安装程序&#xff1a;python-3.12.2-amd64.exe文件&#xff0c;双击启动安装向导。 为了防止C:盘文件因系统故障或者无…