当前位置: 首页 > news >正文

C语言——深入理解指针(4)

目录

1.回调函数

2. qsort 函数的使用

 2.1 排序整型数据

2.2 排序结构体数据

3. qsort 函数的模拟实现


1.回调函数

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

你把函数的地址作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数。该函数不是自己直接调用自己,而是在特点的事件或条件发生时由另外的⼀⽅调⽤的,⽤于对该事件或条件进行响应。

回调函数使用条件: 这些函数的的函数类型都基本一致,只是函数内容上有差距。

#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 = 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: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 函数的使用

qsort是库函数,这个函数可以完成任意类型数据的排序。(使用时包含头文件<stdlib.h>)

void qsort(void*base,//base指向了要排序的数组的第一个元素size_t num,//base指向的数组中的元素个数(待排序的数组的元素的个数)size_t size,//base指向的数组中元素的大小(单位是字节)int(*compar)(const void* p1,const void*p2)//函数指针——指针指向的函数是用来比较数组中的两个元素的。
);

 2.1 排序整型数据

#include <stdio.h>
#include<stdlib.h>
//qsort函数的使⽤者得实现⼀个比较函数
int int_cmp(const void* p1, const void* p2)
{return (*(int*)p1 - *(int*)p2);
}
void print(int* arr,int sz)
{for (int i = 0; i <sz; i++){printf("%d ", arr[i]);}printf("\n");
}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr,sz , sizeof(arr[0]), int_cmp);//(1.数组的第一个元素,2.数组的长度,数组的第一个元素的大小,比较函数接收返回值)print(arr,sz);return 0;
}

2.2 排序结构体数据

struct str
{char name[20];int eag;
};
//怎么比较两个结构体数据?--不能直接使用><==比较
//1.可以按照名字比较
//2.可以按照年龄比较//按照年龄比较
int cmp1(const void* p1, const void* p2)
{return ((struct str*)p1)->eag - ((struct str*)p2)->eag;
}
void test1()
{struct str arr[] = { {"zhangsan",50},{"lisi",60},{"laowang",90} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp1);
}
//按照名字比较
//注意两个字符串不能使用><==比较
//而是使用库函数strcmp来比较的
int cmp2(const void* p1, const void* p2)
{return strcmp(((struct str*)p1)->name, ((struct str*)p2)->name);
}
void test2()
{struct str arr[] = { {"zhangsan",50},{"lisi",60},{"laowang",90} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp2);
}int main()
{test1();test2();printf("\n");return 0;
}

3. qsort 函数的模拟实现

使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。

int int_cmp(const void* p1, const void* p2)
{return (*(int*)p1 - *(int*)p2);
}
void swap(void* p1, void* p2, int size)
{int i = 0;for (i = 0; i < size; i++){char tmp = *((char*)p1 + i);*((char*)p1 + i) = *((char*)p2 + i);*((char*)p2 + i) = tmp;}
}
void bubble(void* base, int count, int size, int(*cmp)(const void*,const void*))
{int i = 0;int j = 0;for (i = 0; i < count - 1; i++){for (j = 0; j < count - i - 1; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;bubble(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;
}

相关文章:

  • apk和小程序渗透测试
  • SQL server 2016安装
  • golang 实现单向链表(lru)、双向链表、双向循环链表
  • 简化控制台日志的输出内容
  • Nacos源码解读03——管理元数据
  • Android : SQLite 增删改查—简单应用
  • 人工智能时代:AIGC的横空出世
  • 二叉树OJ题目——C语言
  • 防爆执法记录仪、防爆智能安全帽助力石油石化行业数智化转型
  • 设计模式-结构型模式之适配器设计模式
  • ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO
  • 3.3 路由器的远程配置
  • 制作一个RISC-V的操作系统-环境搭建
  • C++ string类—初始化、容量操作、迭代器
  • mac 系统 vmware 安装centos8
  • ES6指北【2】—— 箭头函数
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • CentOS6 编译安装 redis-3.2.3
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • ES6简单总结(搭配简单的讲解和小案例)
  • HTML中设置input等文本框为不可操作
  • HTTP那些事
  • SegmentFault 2015 Top Rank
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • supervisor 永不挂掉的进程 安装以及使用
  • vue自定义指令实现v-tap插件
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 给初学者:JavaScript 中数组操作注意点
  • 解析 Webpack中import、require、按需加载的执行过程
  • 深度解析利用ES6进行Promise封装总结
  • 通过几道题目学习二叉搜索树
  • 我的业余项目总结
  • gunicorn工作原理
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #QT(TCP网络编程-服务端)
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • $$$$GB2312-80区位编码表$$$$
  • (07)Hive——窗口函数详解
  • (1)(1.11) SiK Radio v2(一)
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (三)elasticsearch 源码之启动流程分析
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (转)winform之ListView
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • .naturalWidth 和naturalHeight属性,
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .Net Winform开发笔记(一)
  • .net 调用php,php 调用.net com组件 --
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则