【重生之我要苦学C语言】深入理解指针5

深入理解指针5

回调函数

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

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void fun() {printf("hehe\n");
}
void test(void(*pf)()) {if (1)pf();
}
int main() {test(fun);return 0;
}

fun为回调函数

将上篇博文的计算器进行简化:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
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 Mul(int x, int y) {return x * y;
}
int Div(int x, int y) {return x / y;
}
Calc(int (*pf)(int,int)){int a = 0, b = 0, r = 0;printf("请输入两个操作数");scanf("%d%d", &a, &b);r = pf(a, b);printf("%d\n", r);
}
//写一个简易的计算器
//1.实现加减乘除
//2.不需要退出程序可以继续计算
int main() {int input = 0;do{menu();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);case 0:printf("退出计算器");break;default:printf("选择错误,重新选择");break;}} while (input);return 0;
}

qsort(快速排序)

是一个库函数,用来对数据排序
不管是什么类型的数据,它都能排序

void qsort(void* base,size_t num,size_t size,int (*cmp)(const void*,const void*))
void* base//base指向了待排序数组的第一个元素
//qsort函数无法预测你会使用这个函数排序什么类型的数据
size_t num//待排序数据的元素个数
size_t size//待排序数组的第一个元素大小
int (*cmp)(const void*,const void*)//函数指针——指针指向的函数,可以比较base指向的数组中的任意两个元素的大小
//将比较的方法抽离出来,qsort的使用者提供两个元素的比较函数

例1:

升序排序整数:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
//e1指向一个整数,e2指向另外一个整数
int cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2;
}
void print_arr(int arr[], int sz) {int i = 0;for (i = 0;i < sz;i++) {printf("%d ", arr[i]);}printf("\n");
}
int main() {int arr[10] = { 3,1,5,2,9,8,6,4,0,7 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz,sizeof(arr[0]),cmp_int);print_arr(arr, sz);return 0;
}

在这里插入图片描述

如果想要降序进行排序:

int cmp_int(const void* e1, const void* e2) {return *(int*)e2 - *(int*)e1;
}

即可

例2:

void test3() {struct Stu s = { "cuihua",18 };struct Stu* ps = &s;//结构体指针变量printf("%s\n", (*ps).name);printf("%s\n", *ps->name);//结构体变量 .成员名//结构体指针变量 ->成员名
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu
{char name[20];int age;
};
//按照名字来比较
int cmp_stu_by_name(const void* e1, const void* e2) {return strcmp((*(struct Stu*)e1).name , (*(struct Stu*)e2).name);//return strcmp(((struct Stu*)e1)->name , ((struct Stu*)e2)->name);//strcmp比较两个字符串的大小,是按照对应位置上字符的ASCII码值比较的
}
//按照年龄来比较
int cmp_stu_by_age(const void* e1, const void* e2) {return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test2() {struct Stu arr[3] = { {"zhangsan",18},{"lisi",35},{"wangwu",12} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}void test4() {struct Stu arr[3] = { {"zhangsan",18},{"lisi",35},{"wangwu",12} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
}int main() {test2();test4();return 0;
}

使用回调函数,模拟实现qsort

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2;
}
void Swap(char* buf1, char* buf2, size_t n) {int i = 0;for (i = 0;i < n;i++) {char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf2++;buf1++;}
}
void bubble_sort(void* base, size_t sz,size_t width,int(*cmp)(const void* e1,const void* e2)) {int i = 0;int j = 0;for (i = 0;i < sz - 1;i++) {int flag = 0;//假设已经有序for (j = 0;j < sz - 1 - i;j++) {if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {flag = 1;Swap((char*)base + j * width , (char*)base + (j + 1) * width, width);}if (flag == 0) {break;}}}
}
void print_arr(int arr[], int sz) {int i = 0;for (i = 0;i < sz;i++) {printf("%d ", arr[i]);}printf("\n");
}
int main() {//排成升序int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz,sizeof(arr[0]),cmp_int);print_arr(arr, sz);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

IOPaint模型部署教程

一、介绍 IOPaint是一款功能全面且强大的AI图像处理工具&#xff0c;它不仅免费开源&#xff0c;还由SOTA&#xff08;State-of-the-Art&#xff0c;即最先进&#xff09;AI模型驱动&#xff0c;为图像编辑和修复带来了前所未有的便利和高效。以下是对IOPaint的详细介绍&#…

吊打面试官系列:hashCode() 相同,equals() 就一定相等吗?

在编程的世界里&#xff0c;hashCode() 和 equals() 是一对形影不离的好兄弟。它们在Java中定义于Object类中&#xff0c;是每个Java对象都继承的两个方法。但是&#xff0c;如果你认为只要两个对象的hashCode()相同&#xff0c;它们的equals()就一定相等&#xff0c;那你就大错…

阿托伐他汀降脂疗效与安全性真实世界数据整理!

2024年9月&#xff0c;《中国医疗保险》杂志发布了题为《阿托伐他汀仿制药治疗高脂血症疗效与安全性的多中心回顾性队列研究》的重要研究结果。该研究由首都医科大学宣武医院牵头&#xff0c;联合上海交通大学医学院附属瑞金医院、吉林大学第一医院等10家国内顶尖三甲医院共同完…

深入剖析【C++继承】:单一继承与多重继承的策略与实践,解锁代码复用和多态的编程精髓,迈向高级C++编程之旅

​​​​​​​ &#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 继承的概念及定义 继承的概念 继承定义 定义格式 继承基类成员访问⽅式的变化 继承类模板 基类和派⽣类间的转换 继承中的作⽤域 隐藏规则 成员函数的隐藏 考察继承【作⽤…

“嵌入”在大语言模型中是解决把句子转换成向量表示的技术

上一篇&#xff1a;《人工智能是这样理解“情绪”的》 序言&#xff1a;这段话要优化吗&#xff1f;““嵌入”是一种将句子、单词或其他语言单位转换为向量表示的技术。这个向量通常位于高维空间中&#xff0c;它以一种能够表达相似性的方式编码出文本的含义或上下文。嵌入层…

操作系统——内存分区管理

本章主要讨论为什么要给内存进行划分和如何划分的问题。 为了给每一个进程都分配一个大小合适的内存块 以连续存储进程的程序和数据&#xff0c;使得各进程可以并发执行 目录 一、内存的划分方法 1、固定分区法 2、动态分区法 3、动态分区的数据管理结构 二、分区的分配与回…

ML 系列: 第 24 节 — 离散概率分布(泊松分布)

目录 一、说明 二、固定时间间隔示例 三、固定间隔的示例 四、泊松分布的主要特征 五、示例 5.1 平均客户数的计算&#xff1a; 5.2 用于计算和绘制泊松分布的 Python 代码&#xff1a; 一、说明 泊松概率分布是一种离散概率分布&#xff0c;它表示在固定的时间或空间间隔内发生…

【comfyui教程】如何用 ComfyUI 修复和上色老照片?详细教程让老照片焕发新生

前言 如何用 ComfyUI 修复和上色老照片&#xff1f;详细教程让老照片焕发新生 老照片承载着无数回忆&#xff0c;可时光不饶人&#xff0c;随着岁月流逝&#xff0c;它们渐渐变得模糊、泛黄&#xff0c;甚至出现了褪色、裂痕。对于想要留住这份珍贵记忆的人来说&#xff0c;修…

ThinkServer SR658H V2服务器BMC做raid与装系统

目录 前提准备 一. 给磁盘做raid 二. 安装系统 前提准备 磁盘和系统BMC地址都已经准备好&#xff0c;可正常使用。 例&#xff1a; 设备BMC地址&#xff1a;10.99.240.196 一. 给磁盘做raid 要求&#xff1a; 1. 将两个894G的磁盘做成raid1 2. 将两块14902G的磁盘各自做…

BUUCTF pwn2_sctf_2016 int 0x80方法

本文目的 BUUCTF的PWN的第一页的pwn2_sctf_2016的libc不适用辣&#xff0c;但网上一搜全是libc 然后怎么办嘞&#xff0c;都明摆着有个int 0x80&#xff0c;当然是用啊 所以水一篇 早上中午晚上好 老三样&#xff0c;下载程序&#xff0c;打开ida&#xff0c;拖进去 一眼好几…

如何构建一个功能强大的低代码平台网站?关键步骤与技巧全解析

随着数字化转型的加速&#xff0c;企业对敏捷开发和快速迭代的需求越来越迫切。低代码平台应运而生&#xff0c;成为连接业务需求和技术实现的重要桥梁。低代码平台不仅能够大幅降低技术门槛&#xff0c;还能够通过可视化界面和预配置组件简化开发流程&#xff0c;帮助企业快速…

Unity图形学之Shader2.0 模板测试

1.模版测试&#xff1a;符合条件的 通过 不符合条件的 像素 丢弃 比较公式&#xff1a; if&#xff08;&#xff08;referenceValue&readMask&#xff09; comparisonFunction &#xff08;stencilBufferValue&readMask&#xff09;&#xff09; 通过像素 else 抛弃…

RK3588 快速上手

1、资料介绍 我的开发板是临滴科技的LKD3588&#xff0c;相关的官网上都可以找到&#xff0c;我这里给大家一个网盘链接 LKD3588-开发板&#xff08;公开资料&#xff09; https://pan.baidu.com/s/1snYcWY-S4rLMCE_3nGlHrw?pwd3588 LKD3588-开发板&#xff08;保密资料&…

STM32完全学习——点亮LED灯

一、寄存器描述 首先我们知道STM32对外设的操作&#xff0c;是靠对寄存器的设置来完成的。因此我们想要点亮LED灯&#xff0c;就需要知道端口的控制寄存器&#xff0c;然后给寄存器设置不同的值就可以让端口来输出0或1&#xff0c;首先我这里使用的是GPIOA这个端口的0-8位来做…

【Python】如何使用Python-Tkinter打造炫酷动态心形动画 !保姆级教程

文章目录 教程&#xff1a;从零开始&#xff0c;逐步实现动态心形动画环境准备第一步&#xff1a;导入必要的模块第二步&#xff1a;定义画布参数第三步&#xff1a;定义心形生成函数第四步&#xff1a;实现点的散布与收缩第五步&#xff1a;定义曲线函数第六步&#xff1a;创建…

基于SSM的“家政预约管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“家政预约管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 家政预约管理系统功能结构图 系统首页界面 用户注册界面 家政…

MongoDB在现代Web开发中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 MongoDB在现代Web开发中的应用 MongoDB在现代Web开发中的应用 MongoDB在现代Web开发中的应用 引言 MongoDB 概述 定义与原理 发展…

springboot企业信息管理系统,计算机毕业设计项目源码310,计算机毕设程序(LW+开题报告、中期报告、任务书等全套方案)

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;员工信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

【JAVA毕业设计】基于Vue和SpringBoot的周边产品销售网站

博主说明&#xff1a;本文项目编号 T 061 &#xff0c;文末自助获取源码 \color{red}{T061&#xff0c;文末自助获取源码} T061&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

YOLOV8应用|排球垫球计数|附带全部数据集与源码(见文末百度云盘链接)

项目简介: 该项目旨在利用YOLOv8算法实现排球垫球动作的自动识别与计数。YOLOv8作为计算机视觉领域的先进目标检测算法,具备高精度和实时性的特点,非常适合用于体育训练和测试中的自动化计数。项目将排球垫球视频作为输入,通过YOLOv8算法检测视频中的排球及垫球动作,自动…