第十二讲:指针(4)

第十二讲:指针(4)

  • 1.回调函数
    • 1.1什么是回调函数
    • 1.2深入理解并使用回调函数
      • 1.2.1简单写法
      • 1.2.2优化
  • 2.qsort函数详解
    • 2.1函数简单介绍
    • 2.3qsort函数使用举例
      • 2.3.1qsort函数排序整形数据
      • 2.3.2qsort函数排序结构数据
  • 3.qsort函数的模拟实现
    • 3.1冒泡排序
    • 3.2冒泡排序的改造

总结:该篇博客详细对以下两个内容进行讲解:
1.回调函数
2.qsort函数

1.回调函数

1.1什么是回调函数

回调函数就是一个通过函数指针调用的函数

如果我们将函数的地址作为参数传递给另一个函数,当通过这个指针被用来调用其指向的函数时,被调用的函数就是回调函数,回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外一方调用的,用于对该事件或条件进行响应
下面我们通过代码来理解什么是回调函数:

1.2深入理解并使用回调函数

我们写一个简易的计算器

1.2.1简单写法


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("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \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;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;
}

这个方法写的十分冗余,下面我们来进行优化

1.2.2优化


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;
}void calc(int (*pa)(int, int)) //使用函数指针变量来接受函数指针
{printf("请输入两个操作数:\n");int x, y;x = 0;y = 0;scanf("%d %d", &x, &y);int set = pa(x, y);printf("%d\n", set);
}int main()
{int input = 1;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf("*************************\n");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;
}

我们通过画图来理解回调函数:
在这里插入图片描述

在这里插入图片描述

2.qsort函数详解

2.1函数简单介绍

这是一个执行快速排序的函数,包含在<stdlib.h>库中

函数原型:


void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

对各个参数进行介绍如下:

1.base:指向要排序数组的首元素的地址
2.num:数组中的元素的个数
3.width:数组中每个元素的大小,单位是字节
4.int (__cdecl *compare )(const void *elem1, const void *elem2 ):
这是一个由编程者自己写的函数,将函数地址传入,函数的形式被规定,该函数定义了如何比较两个元素

对于自己定义的这个函数,通过其返回值决定所排序元素的顺序,遵循以下原则 :
在这里插入图片描述

2.3qsort函数使用举例

2.3.1qsort函数排序整形数据


//使⽤qsort函数排序整型数据int Sort1(const void* pa, const void* pb)
{return (*(int *)pa - *(int*)pb);
}int main()
{int arr[] = { 2,3,4,5,1,6,7,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), Sort1); //void qsort(void* base, //size_t num, //size_t width, //int(__cdecl * compare)(const void* elem1, const void* elem2));Print(arr, sz);return 0;
}

2.3.2qsort函数排序结构数据


//使⽤qsort函数排序结构数据//创建一个结构类型,假设为学生数据
struct Stu
{char name[20];int age;
};//按照名字排序
int SortByName(const void* pa, const void* pb)
{return (strcmp(((struct Stu*)pa)->name, ((struct Stu*)pb)->name));
}//按照年龄排序
int SortByAge(const void* pa, const void* pb)
{return (((struct Stu*)pa)->age - ((struct Stu*)pb)->age);
}int main()
{//给定学生数据struct Stu arr[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(arr) / sizeof(arr[0]);//按照名字排序qsort(arr, sz, sizeof(arr[0]), SortByName); //void qsort(void* base, //size_t num, //size_t width, //int(__cdecl * compare)(const void* elem1, const void* elem2));//按照年龄排序qsort(arr, sz, sizeof(arr[0]), SortByAge); //void qsort(void* base, //size_t num, //size_t width, //int(__cdecl * compare)(const void* elem1, const void* elem2));return 0;
}

3.qsort函数的模拟实现

我们使用冒泡排序来进行qsort函数的模拟实现,首先先介绍一下什么是冒泡排序

3.1冒泡排序

目前的排序方式有很多,快速排序,希尔排序,冒泡排序,我们现在使用冒泡排序进行类比排序


void BubbleSort(int* pa, int sz)
{for (int i = 0; i < sz - 1; i++){for (int j = 0; j < sz - 1 - i; j++){if (*(pa + j) > *(pa + j + 1)){int temp = *(pa + j);*(pa + j) = *(pa + 1 + j);*(pa + 1 + j) = temp;}}}
}void Print(int* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%d ", *(arr + i));
}int main()
{int arr[] = { 2,3,4,5,1,6,7,9,10 };//冒泡排序int sz = sizeof(arr) / sizeof(arr[0]);BubbleSort(arr, sz);//进行打印Print(arr, sz);return 0;
}

3.2冒泡排序的改造


//冒泡函数的改造
void Change(char* pa, char* pb, int sz)
{for(int i = 0; i<sz; i++){char temp = *pa;*pa = *pb;*pb = temp;pa++;pb++;}
}void BubbleSort(void* pa, size_t sz, size_t width, int(* compare)(const void* pa, const void* pb))
{for (int i = 0; i < sz - 1; i++)  //尽管是改造,但是这两个for循环是不用改变的{                                 //第一个for循环表示循环次数for (int j = 0; j < sz - 1 - i; j++) //第二个for循环是将两个数进行比较{//仍然是判断,如果compare函数返回值大于0,进行交换if (compare((char*)pa + j * width, (char*)pa + (j + 1) * width) > 0)Change((char*)pa + j * width, (char*)pa + (j + 1) * width, width); //进行交换,但是这个交换一次要交换数组类型个字节}}
}int main()
{//给定学生数据struct Stu arr[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };//冒泡排序int sz = sizeof(arr) / sizeof(arr[0]);BubbleSort(arr, sz, sizeof(arr[0]), SortByName);  //void qsort(void* base, //size_t num, //size_t width, //int(__cdecl * compare)(const void* elem1, const void* elem2));BubbleSort(arr, sz, sizeof(arr[0]), SortByAge);return 0;
}

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

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

相关文章

免费PDF批量加密工具

最近在找PDF批量加密的软件来着&#xff0c;发现很多都是需要收费的&#xff0c;当然如果平时工作需要用的比较多&#xff0c;支持一下还是ok的&#xff0c;但是多数人还是偶尔用一下所以没有必要买。 工作用的话&#xff0c;一般企业文件、个人隐私资料、重要合同...所有重要文…

嘎嘎好用的虚拟键盘第二弹之中文输入法

之前还在为不用研究输入中文而暗自窃喜 这不新需求就来了&#xff08;新需求不会迟到 它只是在路上飞一会儿&#xff09; 找到了个博主分享的代码 是好使的 前端-xyq 已经和原作者申请转载了 感谢~~ 原作者地址&#xff1a;https://www.cnblogs.com/linjiangxian/p/16223681.h…

OpenAI推出DALL·E 3识别器、媒体管理器

5月8日&#xff0c;OpenAI在官网宣布&#xff0c;将推出面向其文生图模型DALLE 3 的内容识别器&#xff0c;以及一个媒体管理器。 随着ChatGPT、DALLE 3等生成式AI产品被大量应用在实际业务中&#xff0c;人们越来越难分辨AI和人类创建内容的区别&#xff0c;这个识别器可以帮…

NSSCTF | [LitCTF 2023]我Flag呢?

这道题没啥好说的&#xff0c;题目标签为源码泄露&#xff0c;我们直接CtrlU查看网页源码就能在最后找到flag 本题完

如何用微信小程序实现远程控制4路控制器/断路器

如何用微信小程序实现远程控制4路控制器/断路器呢&#xff1f; 本文描述了使用微信小程序调用HTTP接口&#xff0c;实现控制4路控制器/断路器&#xff0c;支持4路输出&#xff0c;均可独立控制&#xff0c;可接入各种电器。 可选用产品&#xff1a;可根据实际场景需求&#xf…

draw.io 网页版二次开发(1):源码下载和环境搭建

目录 一 说明 二 源码地址以及下载 三 开发环境搭建 1. 前端工程地址 2. 配置开发环境 &#xff08;1&#xff09;安装 node.js &#xff08;2&#xff09;安装 serve 服务器 3. 运行 四 最后 一 说明 应公司项目要求&#xff0c;需要对draw.io进行二次开发&…

福建医疗器械展/2024厦门国际医疗器械展览会重磅来袭

2024中国&#xff08;厦门&#xff09;国际医疗器械展览会 时 间&#xff1a;2024年11月1-3日 November 1-3, 2024 地 点&#xff1a;厦门国际会展中心 Xiamen International Conference & Exhibition Center ​ ◆组织机构 主办单位&#xff1a; 中国技术市场协会医…

Mysql-用户变量的声明与使用

#声明变量 #1.标识符不能以数字开头 #2.只能使用_或$符号&#xff0c;不能使用其他符号 #3.不能使用系统关键字 setuserName刘德华; select userName:刘青云;#将赋值与查询结合 #查询变量、使用变量&#xff0c;匿名的时候建议加上as select userName as 读取到的userName变量…

TriCore:Interrupt 2

今天继续来看看 IR 模块。 名词缩写 缩写全称说明IRInterrupt Router SRService Request 包括&#xff1a; 1. External Resource 2. Internal Resource 3.SW&#xff08;Software&#xff09; SPService Privoder 包括&#xff1a; 1. CPU 2. DMA SRNService Request NodeS…

【linux-IMX6ULL-uboot初次编译及烧录

目录 1. uboot基本概念1. 1 uboot的编译 3. uboot的烧录2. uboot的烧录结果 第一次不进行原理性的探究&#xff0c;也不关注源码内容&#xff0c;只是进行一个直观的了解&#xff0c;对uboot进行初次编译并进烧录到IMX6ULL板卡中 1. uboot基本概念 U-Boot&#xff08;Universa…

java项目之智慧图书管理系统设计与实现(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的智慧图书管理系统设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 智慧图书管理…

GT2712-STBD 三菱触摸屏12.1寸型

GT2712-STBD 三菱触摸屏12.1寸型 GT2712-STBD参数说明&#xff1a;12.1型, SVGA, TFT彩色液晶屏 65536色, 黑色边框, 电源DC24V。 一、三菱触摸屏GT2712-STBD性能规格&#xff1a; [显示部*1*2] . 显示软元件:TFT彩色液晶屏 . GT2712-STBD画面尺寸:12.1寸 . GT2712-STBD…

六级翻译笔记

理解加表达 除了专有名词不能自己理解翻译&#xff0c;其它都可以 时态一般唯一 题目里出现有翻译为 客观存在&#xff1a; there be 单词结尾加er和ee的区别&#xff1a;er是主动&#xff0c;ee是被动 中文句子没有被动&#xff0c;也可以英文翻译为被动 中文的状语可以不是…

使用AudioCraft(MusicGen)生成音乐

AudioCraft 是一个 PyTorch 库,用于音频生成的深度学习研究。AudioCraft 包含两个先进的AI生成模型:AudioGen和MusicGen,它们共同致力于生成高质量的音频内容。 MusicGen是一个简单且可控的音乐生成模型。它利用Meta提供的20K小时授权音乐进行训练,能够根据文本描述或已有…

web后端——netbeans ide +jsp+servlet开发学习总结

目录 jsp基础 netbeans开发工具问题访问网页失败,404,not found 等?HTTP Status 405 - HTTP method POST is not supported......netbeans 提示无法启动GlassFish Server 4.1.1:服务器未运行时, HTTP 或 HTTPS 监听程序端口已被占用404 问题netbeans中项目中有多个html文件,如…

嵌入式RTOS面试题目

用过哪些嵌入式操作系统&#xff1f;使⽤RTOS和裸机代码开发有什么区别&#xff08;优缺点&#xff09;&#xff1f; 之前的⼀个项⽬是采⽤裸机代码开发的&#xff0c;写起来还⾏&#xff0c;通过状态机来管理业务逻辑和各种外设。 但是随着外设的增加&#xff0c;任务之间的…

2024CCPC郑州站超详细题解(含题面)ABFHJLM(河南全国邀请赛)

文章目录 前言A Once In My LifeB 扫雷 1F 优秀字符串H 随机栈J 排列与合数L Toxel 与 PCPC IIM 有效算法 前言 这是大一博主第一次参加xcpc比赛&#xff0c;虽然只取得了铜牌&#xff0c;但是收获满满&#xff0c;在了解了和别人的差距后会更加激励自己去学习&#xff0c;下面…

基于PHP高考志愿填报系统搭建私有化部署源码

金秋志愿高考志愿填报系统是一款为高中毕业生提供志愿填报服务的在线平台。该系统旨在帮助学生更加科学、合理地选择自己的大学专业和学校&#xff0c;从而为未来的职业发展打下坚实的基础。 该系统的主要功能包括:报考信息查询、志愿填报数据指导、专业信息查询、院校信息查询…

面向对象设计之套路——设计模式

1、总则 面向对象的分析设计编程思想&#xff0c;通过封装、继承、多态把程序的耦合度降低&#xff0c;用设计模式使得程序更加灵活&#xff0c;容易修改&#xff0c;并且易于复用。 让业务逻辑与界面逻辑分开&#xff0c;让它们的耦合度下降&#xff0c;只有分离&#xff0c;…

Tableau学习2.0版——复习

官网下载链接&#xff1a;https://www.tableau.com/zh-cn/support/releases 学生账户申请链接&#xff1a;https://www.tableau.com/zh-cn/academic/students。直接去学信网下载学籍在线验证作为申请证明。 目录 1、可视化原理 2、基础图表制作 2.1 对比分析&#xff08;比…