【C/C++】深入理解指针(五)
深入理解指针(五)1.回调函数是什么回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针地址作为参数传递给另⼀个函数当这个指针被⽤来调⽤其所指向的函数时被调用的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的⽤于对该事件或条件进⾏响应。在深入理解指针四**(可以移步主页)**中我们写的计算机的实现的代码中红⾊框中的代码是重复出现的其中虽然执⾏计算的逻辑 是区别的但是输⼊输出操作是冗余的有没有办法简化⼀些呢可以将相似代码抽象成函数因为红⾊框中的代码只有调⽤函数的逻辑是有差异的我们可以把调⽤的函数的地址以参数的形式 传递过去使⽤函数指针接收函数指针指向什么函数就调⽤什么函数这⾥其实使⽤的就是回调函 数的功能。有了函数指针后函数的调用可以使用函数名调用也可以使用函数指针来调用代码语言javascriptAI代码解释//使⽤回调函数改造前 #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(*************************\n); printf( 1:add 2:sub \n); printf( 3:mul 4:div \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; }代码语言javascriptAI代码解释//使⽤回调函数改造后 #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; } 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 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 使用qsort函数排序整型数据qsort是库函数可以排序任意类型的数据底层使用的是快速排序的方式(头文件为(stdlib.h)在这里插入图片描述下边对qsort个参数进行解释代码语言javascriptAI代码解释void qsort(void* base,//指针指向的是待排序的数组的第一个元素 size_t num,//base指向的待排序数组的元素的个数 size_t size,//base指向待排序数组元素的大小 int(*compar)(const void*, const void*)//函数指针 );qosrt 函数有实现者qosrt 函数的使用者 —-明确的知道要排序的是什么数据这些数据应该如何比较所以提供两个元素的比较函数在深入理解指针三中,我们提到了冒泡排序代码如下代码语言javascriptAI代码解释#includestdio.h void bubble_sort(int arr[], int sz) { int i 0; for (i 0; i sz - 1; i) { int j 0; for (j 0; j sz - 1 - i; j) { if (arr[j] arr[j 1]) { int tmp arr[j 1]; arr[j 1] arr[j]; arr[j] tmp; } } } } void print_arr(int arr[], int sz)//参数写成数组的形式本质上还是指针 //形参的数组是不会再单独创建数组空间的所以形参的数组是可以省略掉数组大小不写的 { int i 0; for (i 0; i sz; i) { printf(%d , arr[i]); } } int main() { int arr[] { 9,8,7,6,5,4,3,2,1 }; //排为升序 int sz sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); print_arr(arr, sz); }很容易发现该代码只适用于整数那么在使用冒泡排序的情况下要改造函数让它能够排序任意类型的数据该如何做到问题的主要原因是两个整型元素可以直接用比较但是两个字符串、两个结构体是不能用比较的参数以及数据的交换也需要更改我们可以把两个元素的比较封装成函数然后把函数地址传给排序函数代码语言javascriptAI代码解释#include stdio.h //qosrt函数的使⽤者得实现⼀个⽐较函数 int int_cmp(const void* p1, const void* p2) { //强制类型转换 if(*(int *)p1*(int *)p2)//此处不能写成if(*p1*p2) 因为void*类型的指针是无具体类型的指针这种类型的指针不能直接解引用也不能-整数运算 return 1; else if(*(int *)p1*(int *)p2) return 0; else return -1; } 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; }强调void*类型的指针是无具体类型的指针这种类型的指针不能直接解引用也不能±整数运算最后我们对代码做一下简化代码语言javascriptAI代码解释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; }2.2 使用qsort排序结构数据这⾥需要补充介绍结构指针和结构体成员访问操作符 -;代码语言javascriptAI代码解释结构体变量.成员名 结构体指针-成员名结构体补充:代码语言javascriptAI代码解释struct Stu//学生 { char mane[20];//名字 int age;//年龄 }; int main() { struct Stu s{zhangsan,18}; printf(%s %d,s.name,s.age); return 0; }代码语言javascriptAI代码解释void print(struct Stu* ps) { //printf(%s %d,(*ps).name,(*ps).age); //可以但是啰嗦 printf(%s %d,ps-name,ps-age);//这两者等价 } struct Stu//学生 { char mane[20];//名字 int age;//年龄 }; int main() { struct Stu s{zhangsan,18}; print(s); return 0; }这两个结构体怎么比1.按照名字比较————-字符串比较—–strcmp头文件为string.h2.按照年龄比较————-整型比较那strcmp函数是怎么比较字符串大小的呢

相关新闻

Flutter 三方库 ory_client 的鸿蒙化适配指南 - 掌控身份认证资产、精密 Identity 治理实战、鸿蒙级授权专家

Flutter 三方库 ory_client 的鸿蒙化适配指南 - 掌控身份认证资产、精密 Identity 治理实战、鸿蒙级授权专家

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net Flutter 三方库 ory_client 的鸿蒙化适配指南 - 掌控身份认证资产、精密 Identity 治理实战、鸿蒙级授权专家 在鸿蒙跨平台应用执行高级身份识别管理与多维 Ory Cloud 资产指控&#xff08…

2026/7/6 0:11:20 阅读更多 →
ShardingSphere-jdbc 5.5.0 + spring boot 基础配置 - 实战篇

ShardingSphere-jdbc 5.5.0 + spring boot 基础配置 - 实战篇

ShardingSphere-jdbc 5.5.0 spring boot 基础配置 环境准备 版本数据库说明 集群 配置 配置文件Maven依赖spring boot配置shardingsphere-jdbc配置 自定义配置1:SM4加解密存储数据完整的基础配置 其他 雪花算法自定义worker.id 环境准备 版本 spring boot 2.…

2026/7/6 0:12:56 阅读更多 →
大模型知识梳理(持续更新)

大模型知识梳理(持续更新)

大模型的底层——TrasnsformerTransformer 架构是一种基于自注意力机制(Self-Attention)的深度学习模型,由 Google 团队在 2017 年的论文《Attention Is All You Need》中首次提出。它改变了自然语言处理(NLP)领域&…

2026/5/17 9:32:58 阅读更多 →

最新新闻

位置编码外推实战:从BERT 512到26万token的3种延拓策略

位置编码外推实战:从BERT 512到26万token的3种延拓策略

位置编码外推实战:从BERT 512到26万token的3种延拓策略当处理长文本序列时,BERT等Transformer模型面临一个根本性限制——位置编码的长度约束。传统BERT模型最多只能处理512个token,这严重制约了其在长文档理解、基因组分析等场景的应用潜力。…

2026/7/6 0:11:20 阅读更多 →
如何彻底告别重复点击:AutoClicker鼠标自动化完全指南

如何彻底告别重复点击:AutoClicker鼠标自动化完全指南

如何彻底告别重复点击:AutoClicker鼠标自动化完全指南 【免费下载链接】AutoClicker AutoClicker is a useful simple tool for automating mouse clicks. 项目地址: https://gitcode.com/gh_mirrors/au/AutoClicker 还在为每天重复的鼠标点击任务感到疲惫吗…

2026/7/6 0:11:20 阅读更多 →
DQN 算法实战:CartPole-v0 环境 1000 轮训练实现 200 分满分

DQN 算法实战:CartPole-v0 环境 1000 轮训练实现 200 分满分

DQN算法实战:从零构建CartPole智能体的完整指南1. 环境准备与基础概念在开始构建DQN智能体之前,我们需要先理解几个核心概念。CartPole-v0是OpenAI Gym中的一个经典控制问题,目标是让小车上的杆子保持直立不倒下。这个环境有四个状态变量&…

2026/7/6 0:11:20 阅读更多 →
OpenCV 4.8 双目立体匹配实战:BM/SGBM/GC 3种算法在Middlebury数据集上的精度与速度对比

OpenCV 4.8 双目立体匹配实战:BM/SGBM/GC 3种算法在Middlebury数据集上的精度与速度对比

OpenCV 4.8 双目立体匹配实战:BM/SGBM/GC算法在Middlebury数据集上的精度与速度对比双目立体视觉作为三维重建的核心技术之一,其核心挑战在于如何高效准确地计算左右图像间的视差图。OpenCV作为计算机视觉领域的瑞士军刀,提供了Block Matchin…

2026/7/6 0:07:19 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻