深⼊理解指针(5)[回调函数、qsort相关知识(qsort可用于各种类型变量的排序)】

devtools/2024/11/14 4:05:29/
目录
1. 回调函数
2. qsort相关知识(qsort可用于各种类型变量的排序)

一      回调函数

     1定义/作用:把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,(作用)⽤于对该事件或条件进⾏响应。

    2好处:(下面我们来看两个效果相同的代码,比较它们的简约程度)

代码1(未使用回调函数

 

 代码2(使用回调函数

 总结:这里我们使用回调函数,使得重复得部分得到了优化,代码变得更加简约。

二      qsort相关知识

1形式:

void qsort
(
     void* base//base->待排序数组中的首元素
     size_t num//待排序数组中的元素个数因为元素个数不可能是负数所以用size_t定义
     size_t size//待排序数组中的一个元素的大小因为一个元素的大小不可能是负数所以用        size_t定义
    int* (*cmp)(const void*,const void*)//函数指针--指针指向的函数,可用于比较base指向的数组中任何两个元素的大小。  因为用于比较的数组类型不同所以用void定义,又因为我们只对数据进行排序而不对数据进行改变所以用const修饰,防止数据被改写
    
)

2   qsort 使⽤举例

2.1使⽤qsort函数排序整型数据

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数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函数排序结构数据(要指明排序类型例如描述一个人是使用结构体可能含有姓名,性别等,这时候就要指明你要排序的数据如要对姓名就要指明姓名)

按照名字来排序

 注意在按照名字进行比较时和整型有所不同,因为名字是字符串,要用strcmp函数。

按照年龄来⽐较

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

主体框架

注意我们这里要模仿qsort函数,对其冒泡排序设置参数

排序的实现

 注意这里和冒泡排序有所不同的是在于冒泡排序只对整型排序直接比较即可,而我们这里比较两个元素的大小是通过字符类型来比较因为每个整数数组中的元素都是占4个字节,所以要用强制类型转换将其转换为char*型,而这里的width表示的是整型数组中一个元素的长度,所以这里的(char*)base + j * width,和(char*)base+(j + 1) * width表示第j个元素和第j+1个元素

函数的声明

实现交换

因为一个整型占4个字节无法进行交换,这时候我们将其划分为一个一个字节,将其强制类型转换为字符型char*,然后我们只要将两个元素的4个字节一一交换即可。

 这里的n表示的是width(4),因为一个整型占4个字节,而我们前面将其强制类型转换为字符型char*,这时候我们只要将两个元素的4个字节一一交换即可。

整体代码

#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;buf1++;buf2++;}
}void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
{int i = 0;//趟数for (i = 0; i < sz - 1; i++){//一趟内部的排序int j = 0;for (j = 0; j < sz - i - 1; j++){if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0){//判断是否满足条件,满足则进行交换swap((char*)base + j * width, (char*)base+(j + 1) * width, width);}}}
}
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}
void test()
{int arr[] = { 9,8,7,6,5,4,3,2,1,10};int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);//模仿qsort函数,对其设置参数print(arr, sz);//打印
}
int main()
{test();return 0;}

    本篇文章就到此结束,希望有所能帮到 读者更好的了解指针。


http://www.ppmy.cn/devtools/133407.html

相关文章

.net core开发windows程序在国产麒麟操作系统中运行

.net core自从3.1版本号后&#xff0c;完全是一个独立的开源的多平台开发组件&#xff0c;目前国产化是趋势&#xff0c;不少项目需要开发国产如Kylin操作系统中运行的程序&#xff0c;无论是Web程序还是桌面程序&#xff0c;都有这样的需求。 首先&#xff0c;可明确的的.net…

如何在CentOS 7上搭建SMB服务

如何在CentOS 7上搭建SMB服务 因项目测试需求&#xff0c;需要自行搭建SMB服务&#xff0c;**SMB&#xff08;Server Message Block&#xff09;**协议是一种常用的文件共享方式&#xff0c;它可以让不同操作系统之间共享文件、打印机等资源。本文将带你一步步搭建一个简单的S…

c文件的编译,汇编,基础知识

文章目录 前言一、预编译二、编译阶段三、汇编1&#xff0c; objdump的用法2&#xff0c;objdump 举例objdump -s hello.o 输出&#xff08;节内容&#xff09; 四&#xff0c;代码段 前言 #include <stdio.h> int main(){printf("hello, world\n");}从这个最…

Python学习从0到1 day26 第三阶段 Spark ① 数据输入

要学会 剥落旧痂 然后 循此新生 —— 24.11.8 一、Spark是什么 定义&#xff1a; Apache Spark 是用于大规模数据处理的统一分析引擎 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算TB、PB乃至EB级别的海量数据…

电子商务网站之首页设计

本文 以表格布局方式实现一电 子商务网站首页&#xff0c;结合php[mysql获取后端数据 。首页通常包括网店Logo、导航条、搜索、商品展示等&#xff0c;网页头部和脚部已经制作成两件&#xff0c;直接调用即可&#xff0c;导航还需设计一个商品类别导航&#xff0c;商品展示分为…

基于微信小程序的移动学习平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…

ubuntu更改max_map_count

在Ubuntu系统中&#xff0c;max_map_count是一个内核参数&#xff0c;用于限制每个进程可以拥有的内存段的数量。对于Elasticsearch等需要大量内存映射的应用&#xff0c;可能需要增加这个值。 执行以下步骤来更改max_map_count的值&#xff1a; 打开终端。 输入以下命令以编…

SpringBoot框架在资产管理中的应用

3系统分析 3.1可行性分析 通过对本企业资产管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本企业资产管理系统采用Spring Boot框架&#xff0c;JAVA作…