指针(4)

1.回调函数

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

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

计算器的实现:

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;
}void calc(int(*pf)(int,int))//传过来的是函数的地址,要用函数指针变量来接收
{int x = 0;int y = 0;int ret = 0;printf("请输入两个操作数:");scanf("%d %d", &x, &y);ret = pf(x, y);printf("%d\n", ret);
}int main()
{int input = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1://calc功能强大了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 函数排序整形数据

#include<stdlib.h>
void print_arr(int arr[],int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}//cmp_int 这个函数是用来比较p1和p2指向元素的大小// cmp—函数的使用者提供,谁使用谁提供//cmp函数中的参数类型必须和 test() 函数中的qsort中的第四个参数类型保持一致才可以传过去
int cmp_int(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;}//测试qsort排序整型数据
void test1()
{int arr[10] = { 5,3,2,1,0,9,8,4,7,6 };int sz = sizeof(arr) / sizeof(arr[0]);print_arr(arr,sz);qsort(arr, sz, sizeof(arr[0]), cmp_int);//qsort 函数底层用的是快速排序print_arr(arr,sz);
}
int main()
{test1();//用来实现整型数据的排序return 0;
}

2.2使用qsort排序结构数据

//测试qsort排序结构体数据struct Stu
{char name[20];int age;};//比较2个结构体的数据???
//不能直接使用 < > == 来比较
// 
//1.按照名字来比较
//2.按照年龄来比较//按照年龄来比较
int cmp_stu_by_age(const void* p1, const void* p2)
{return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;//升序//                   p2                       p1       //降序//(*(struct Stu*)p1).age
}
//-> 仅限于结构体指针运用
//结构体指针->成员名
//结构体变量.成员名#include<string.h>
//按照姓名来比较:比较对应位置上的字母相对应的ASCII码值
//两个字符串是不能使用 >  < == 来进行比较的
//比较字符串是 strcmp - string compare 返回类型和
//int cmp_stu_by_name(const void* p1, const void* p2) 一样: <0 >0 =0 
//所以直接 return 0 返回
int cmp_stu_by_name(const void* p1, const void* p2)
{return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}test2()
{struct Stu arr[] = { {"xiaoming",14},{"xiaohong",16},{"xiaolan",17} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);}test3()
{struct Stu arr[] = { {"xiaoming",14},{"xiaohong",16},{"xiaolan",17} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);}
int main()
{test1();//用来实现整型数据的排序test2();//用来实现结构体指针数据的排序test3();//按照结构体年龄来排序return 0;
}

3.qsort函数的模拟实现

使用回调函数,模拟实现qsort的功能(采用冒泡排序)

代码中使用 void * 的指针,是方便接收任何类型的地址,以此来实现任何类型的排序

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int cmp_int(const void* p1, const void* p2)
{return (*(int*)p1 - *(int*)p2);
}void Swap(char *buf1, char *buf2, size_t width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}}
//参照qsort(arr, sz,sizeof(arr[0]),cmp_int);来写bubble_sort2函数
void bubble_sort2(void* base, size_t sz, size_t width, int(*cmpar)(const void* p1, const void* p2))
//只希望接收p1和p2的地址,不想由任何的改变,所以加上const
{int i = 0;for (i = 0; i < sz; i++)//趟数不变,这个不变{int j = 0;for (j = 0; j < sz - 1 - i; j++)//每相邻的元素的比较不变,这个也不变{//if (arr[j] > arr[j + 1]) 不再是数组—>改变if(cmpar((char*)base+j*width,(char*)base+(j+1)*width)>0){/*int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;*///交换-->也变Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);}}}
}void test3()
{int arr[10] = { 2,6,4,8,9,3,0,1,7,5 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort2(arr, sz, sizeof(arr[0]), cmp_int);print_arr(arr, sz);
}struct Stu //学生
{char name[20];int age;
};
int cmp_stu_by_age(const void*p1,const void*p2)
{return ((struct Stu*)p1)->age - ((struct Stu *)p2)->age;
}int cmp_stu_by_name(const void* p1, const void* p2)
{return strcmp(((struct Stu*)p1)->name,((struct Stu*)p2)->name);
}
void test4()
{struct Stu arr[] = { {"mingxiao",25},{"hongxiao",27},{"lanxiao",23} };int sz = sizeof(arr) / sizeof(arr[0]);//bubble_sort2(arr, sz, sizeof(arr[0]), cmp_stu_by_name);bubble_sort2(arr, sz, sizeof(arr[0]), cmp_stu_by_age);//打印数组内容int i = 0;for (i = 0; i < sz; i++){printf("%s %d\n", arr[i].name, arr[i].age);}}int main()
{//test1();//冒泡排序实现数组的升序//test2();//用qsort函数来实现数组的升序test3();//自己用bubble_sort2来实现qsort函数的功能,以此来达到实现能够排序任意类型数据的目的//1.先实现bubble_sort2()函数,再进行后续的操作//2.bubble_sort2()函数里面两个相邻函数的比较以及交换test4();//用bubble_sort2()函数来实现结构体的中数据的排序return 0;
}

 在Swap中用 char * 来接收是为了方便交换,特别是结构体类型的数据,大小是不确定的,可能是4字节、16字节、23字节等等,根据使用者自己编写的代码来分配大小,一个一个字节的交换可以实现单数(9)字节大小的单位的类型交换,来达到实现任意类型数据的交换。

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

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

相关文章

Raptor码的解码成功率matlab实现

下面是使用matlab实现关于Raptor 码解码成功率的仿真代码&#xff0c;并绘制成功率随编码符号数量变化的图形示例。代码中包含了 Raptor 码的预编码&#xff08;使用稀疏矩阵乘法模拟&#xff09;、LT 编码、解码过程&#xff0c;以及解码成功率的计算和绘图。 具体代码如下&am…

域名系统DNS

DNS介绍 DNS是一个域名系统&#xff0c;在互联网环境中为域名和IP地址相互映射的一个分布式数据库 &#xff0c; 能够使用户更方便的访问互联网&#xff0c;而不用去记住能够被机器直接读取的IP数串。类似于生活中的114服务&#xff0c;可以通过人名找到电话号码&#xff0c;也…

Spark Streaming核心编程总结(四)

一、有状态转化操作&#xff1a;UpdateStateByKey 概念与作用 UpdateStateByKey 用于在流式计算中跨批次维护状态&#xff08;如累加统计词频&#xff09;。它允许基于键值对形式的DStream&#xff0c;通过自定义状态更新函数&#xff0c;将历史状态与新数据结合&#xff0c;生…

Dijkstra 算法代码步骤[leetcode.743网络延迟时间]

有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源节点&#xff0c;vi 是目标节点&#xff0c; wi 是一个信号从源节点传递到目标节点的时间。 现在&#xff0c;…

【java】lambda表达式总结

目录 一、面向对象的处理方法 二、函数式编程的处理方法 先使用匿名内部类&#xff1a; lambda改造&#xff1a; lambda改造规则 示例&#xff1a; 三、补充&#xff1a;函数式接口 大家好&#xff0c;我是jstart千语。今天总结一下lambda表达式。lambda表达式在后面的s…

AtCoder Beginner Contest 242 G - Range Pairing Query (莫队)

每周五篇博客&#xff1a;&#xff08;5/5&#xff09; 我做到了&#xff01; https://atcoder.jp/contests/abc242/tasks/abc242_g 这题主要是想给大家提供一份莫队的板子&#xff0c;很多莫队题基本上填空就差不多了&#xff08; 板子 void solve() {int n;std::cin >…

淘宝商品主图标题api接口

1、输入淘宝商品id或者链接&#xff0c;点查询 2、查询淘宝商品主图&#xff0c;商品标题&#xff0c;商品价格&#xff0c;卖家旺旺 3、支持api接口

文心一言开发指南06——千帆大模型平台新手指南

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 千帆大模型平台为新手用户提供了一个全面的入门指南&#xff0c;以便用户能够快速熟悉平台的操作和功能。千帆大模型平台通过提供详细的新手指南&#xff0c;确保用户能够顺…

Pacman-N-queen

文档 代码及文档&#xff1a;通过网盘分享的文件&#xff1a;code 链接: https://pan.baidu.com/s/1Rgo9ynnEqjZsSP2-6TyS8Q?pwdn99p 提取码: n99p 补充核心代码 核心代码内容&#xff1a; genetic_algorithm,py # -*- coding: utf-8 -*- """ Created on …

常用的多传感器数据融合方法

1. 概述 根据具体需求&#xff08;实时性、计算资源、噪声特性&#xff09;选择合适的方法&#xff0c;实际应用中常结合多种方法&#xff08;如UKF与神经网络结合&#xff09;。 传统方法 &#xff08;KF/EKF/UKF/PF&#xff09;依赖数学模型&#xff0c;适合动态系统&#…

简单几步,开启 Intel VT-x 让电脑“解开CPU封印”

#vmware #虚拟机 #cpu虚拟化 # Intel VT-x 前言 你是不是也遇到过这种情况&#xff1a;在尝试运行虚拟机&#xff08;VM&#xff09;、安卓模拟器&#xff0c;或者使用 Windows 沙盒、WSL2 等功能时&#xff0c;遇到了类似“此主机支持 Intel VT-x&#xff0c;但 Intel VT-x …

Go语言--语法基础4--基本数据类型--字符串类型

在 Go 语言中&#xff0c;字符串也是一种基本类型。相比之下&#xff0c; C/C 语言中并不存在原 生的字符串类型&#xff0c; 通常使用字符数组来表示&#xff0c;并以字符指针来传递。 Go 语言中字符串的声明和初始化非常简单&#xff0c;举例如下&#xff1a; var str st…

QT中的事件及其属性

Qt中的事件是对操作系统提供的事件机制进行封装&#xff0c;Qt中的信号槽就是对事件机制的进一步封装 但是特殊情况下&#xff0c;如对于没有提供信号的用户操作&#xff0c;就需要通过重写事件处理的形式&#xff0c;来手动处理事件的响应逻辑 常见的Qt事件&#xff1a; 常见事…

socket套接字-UDP(中)

socket套接字-UDP&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/147465441?fromshareblogdetail&sharetypeblogdetail&sharerId147465441&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link UDP服务器…

C++入门小馆: STL 之queue和stack

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

ALTER TABLE 删除DROP表列的报错: 因为有一个或多个对象访问此列

目录 1.问题 2.解决办法 1.问题 删除某个列名的时候&#xff0c;提示错误因为有一个或多个对象访问此列 2.解决办法 2.1 添加或删除表新列名 将表中的字段设置Default 或 NOT NULL 都会给该字段添加约束&#xff0c;增加了这些约束后&#xff0c;再SQL脚本修改类型、删除会发生…

python源码打包为可执行的exe文件

文章目录 简单的方式&#xff08;PyInstaller&#xff09;特点步骤安装 PyInstaller打包脚本得到.exe文件 简单的方式&#xff08;PyInstaller&#xff09; 特点 支持 Python 3.6打包为单文件&#xff08;–onefile&#xff09;或文件夹形式自动处理依赖项 步骤 安装 PyIns…

【2025最近Java面试八股】Spring中循环依赖的问题?怎么解决的?

1. 什么是循环依赖&#xff1f; 在Spring框架中&#xff0c;循环依赖是指两个或多个bean之间相互依赖&#xff0c;形成了一个循环引用的情况。如果不加以处理&#xff0c;这种情况会导致应用程序启动失败。导致 Spring 容器无法完成依赖注入。 例如&#xff1a; Service publi…

JimuBI 积木报表 v1.9.5发布,大屏和仪表盘,免费数据可视化

项目介绍 JimuBI (积木报表BI) 是一款免费的数据可视化产品&#xff0c;含大屏和仪表盘、门户、移动图表&#xff0c;像搭建积木一样完全在线设计&#xff01; 大屏采用类word风格&#xff0c;可以随意拖动组件&#xff0c;想怎么设计怎么设计&#xff0c;可以像百度和阿里一样…

云原生课程-Docker

一次镜像&#xff0c;到处运行。 1. Docker详解&#xff1a; 1.1 Docker简介&#xff1a; Docker是一个开源的容器化平台&#xff0c;可以帮助开发者将应用程序和其依赖的环境打包成一个可移植的&#xff0c;可部署的容器。 docker daemon:是一个运行在宿主机&#xff08;DO…