C语言之指针详解(7)

news2024/11/19 17:27:11
目录
本章重点
1. 字符指针
2. 数组指针
3. 指针数组
4. 数组传参和指针传参
5. 函数指针
6. 函数指针数组
7. 指向函数指针数组的指针
8. 回调函数
9. 指针和数组面试题的解析
上一篇博客我们说过会把回调函数的一些知识再给大家讲一遍
这里把void*强制类型转化为struct Stu*,用->操作符找到age这个元素,然后对年龄进行快速排序

//void qsort(void* base, size_t num, size_t size,int (*compar)(const void*e1, const void*e2));
#include<stdio.h>
#include<stdlib.h>
struct Stu
{
	char name[20];
	int age;

};
int cmp_stu_by_age(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test()
{
	struct Stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
int main()
{
	test();
	return 0;
}
那我们如果要将字符串进行快速排序,我们还是按照age的排序方式来排序嘛?答案是不是,这里我们要用到字符串比较函数strcmp,现在我们来看下列代码,F11走到函数内部进行排序,我们看到的结果就是lisi  wangwu zhangsan
//void qsort(void* base, size_t num, size_t size,int (*compar)(const void*e1, const void*e2));
#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)
{
	//比较名字就是比较字符串
	//字符串比较不能直接<>=来比较,需要用到strcmp函数
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
	//return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test()
{
	struct Stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
	test();
	return 0;
}
这里再次给大家把qsort函数强调一下
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

第一个参数:待排序数组的首元素的地址

第二个参数:待排序数组的元素个数

第三个参数:待排序数组的每个元素的大小,单位为字节

第四个参数:是函数指针,比较两个元素的所用函数的地址,这个函数使用者自己实现,函数指针的两个参数是待比较的两个元素的地址

#include <stdio.h>
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)(void*, 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 };
	//char *arr[] = {"aaaa","dddd","cccc","bbbb"};
	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;
}

这里给大家详细解释一下这个代码

为什么我们要写cmp((char*)base + j * size, (char*)base + (j + 1) * size)呢???

因为当j=0的时候,这个函数的参数就代表第一个元素和第二个元素的地址,强制类型转化为char*而不是Int*的原因是强制类型转化为Int*然后+1会让地址向后移动四个字节,对于如果我们给你传过来的是一个结构体类型,double型,float型就不合适,所以Int*不考虑,对于为什么要强制类型转换为char*指针,char*指针加1跳过一个字节,当我+size的时候就跳过size个字节,这是我们就把我们相邻两个元素的地址求出来了,然后把地址带到cmp这个函数中去了,但他返回cmp函数的值大于0,我们就进行交换,那我们应该怎么交换呢???这里我们就设计一个_swap函数,传的参数是(char*)base + j * size, (char*)base + (j + 1) * size, size,我们为什么还要传一个size呢?因为你应该告诉我你这个两个字符各是几个字节,让我交换相应的对数,所以我们应该把这个元素的大小传过去,我们进到_swap函数进行交换,交换完了过后再*p1++,*p2++指向下一个值 ,再进行下一组交换,接着我们再写出这行代码,看下面代码,进行正负数的返回,返回给cmp函数判断正负数,是整数就进行交换,希望大家能够理解

#include <stdio.h>
int int_cmp(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}

这是一个一般的冒泡排序的模型,上面的代码就只是这个一般的冒泡排序的一个升华,本质是没变的,里面的排序还是正常的将两个元素进行交换,直到交换成升序为止

这里再给大家做一下说明

使用bubble_sort的程序员一定要知道自己排序的是什么数据,他就应该知道如何比较待排序数组中的元素,实现bubble_sort函数的程序员,他不知道未来排序的数据类型,那程序员也不知道待比较的两个元素的类型

本章终!

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

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

相关文章

【Hadoop】 | 搭建HA之报错锦集

知识目录 一、写在前面✨二、Hadoop的active结点无法主备切换&#x1f525;三、Hadoop Web端无法上传文件&#x1f349;四、hdfs创建文件夹报错&#x1f36d;五、IDEA操作Hdfs无法初始化集群&#x1f525;六、Java无法连接Hdfs&#x1f36d;七、找不到Hadoop家目录&#x1f525…

软件测试实战案例:支付功能板块如何测试?详细总结

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 大体上&#xff0…

ChatGPT数据安全隐患?本想提高效率,数据却遭泄露

一项新的研究发现&#xff0c;15%的员工经常在ChatGPT上上传公司数据&#xff0c;其中超过四分之一的数据被认为是敏感信息&#xff0c;这使公司在无形中面临安全漏洞的风险。 6月的研究报告《揭示真正的GenAI数据暴露风险》分析了超过10000名员工&#xff0c;主要研究员工如何…

(ICIP-2022)GAITTAKE:通过时间注意和关键点引导嵌入进行步态识别

GAITTAKE&#xff1a;通过时间注意和关键点引导嵌入进行步态识别 论文题目&#xff1a;GAITTAKE: GAIT RECOGNITION BY TEMPORAL ATTENTION AND KEYPOINT-GUIDED EMBEDDING 论文是华盛顿大学发表在ICIP 2022的工作 论文地址 ABSTRACT 步态识别是指根据远距离采集的视频数据&am…

【服务器数据恢复】OneFS文件系统下误删除文件的数据恢复案例

EMC Isilon存储结构&#xff1a; Isilon群集存储系统使用的是分布式文件系统OneFS。Isilon群集存储系统的每个节点均为单一OneFS文件系统&#xff0c;Isilon在进行横向扩展时不会影响数据的正常使用。Isilon群集存储系统所有节点在工作时都提供相同的功能&#xff0c;节点没有主…

js数组高阶函数——map()方法

js数组高阶函数——map方法 map&#xff08;&#xff09;语法map&#xff08;&#xff09;的基本使用map&#xff08;&#xff09;的优缺点map&#xff08;&#xff09;的使用场景去重双重for循环配合splie去重map循环配合Array.from去重set&#xff08;&#xff09;去重filter…

es中索引那些事

0、前言 在了解倒排索引之前先理解下索引的作用&#xff1a; 查询数据的时候&#xff0c;最耗时的操作并不是CPU计算&#xff0c;也不是内存聚合&#xff0c;而是去磁盘将文档查到并拉取回来的过程。我们都知道在磁盘IO的过程中&#xff0c;顺序读写效率高于随机读写&#xf…

JavaWeb学习路线(4)——请求响应与分层解耦

一、概述 二、请求 &#xff08;一&#xff09;概念&#xff1a; 全名为HttpServletRequest&#xff0c;其目标是获取请求数据。 &#xff08;二&#xff09;简单请求&#xff1a; web端发送基本数据类型数据到服务器进行处理。 1、获取方式 &#xff08;1&#xff09;原…

ESP32学习之JSON,和接入心知天气

注意&#xff1a;手机热点或者网络不能开5.0GHz频段和WIFI6&#xff0c;不然ESP32连不上 心知天气账号&#xff08;免费版即可&#xff09;&#xff0c;网站&#xff1a;心知天气 - 高精度气象数据 - 天气数据API接口 - 行业气象解决方案 (seniverse.com) V3的用户手册-天气实…

【业务功能篇29】Assert断言

业务场景&#xff1a; 当我们需要对一个接口方法验证是&#xff0c;在单元测试中&#xff0c;主要用于程序代码的调试或测试阶段 基本的使用就是assert condition&#xff0c;当 condition 为 true&#xff0c;就继续往下运行&#xff1b;当 condition 为 false&#xff0c;就抛…

MySQL - 第2节 - MySQL库的操作

1.创建数据库 创建数据库的SQL如下&#xff1a; CREATE DATABASE [IF NOT EXISTS] db_name [[DEFAULT] CHARSETcharset_name] [[DEFAULT] COLLATEcollation_name];说明&#xff1a; • SQL中大写的表示关键字&#xff0c;[ ]中代表的是可选项。 • CHARSET用于指定数据库所采用…

「实在RPA·证券数字员工」革新证券数字化现状

2022年1月《金融科技发展规划&#xff08;2022——2025年&#xff09;》提出“十四五”时期金融科技发展愿景&#xff0c;明确了金融科技发展的指导思想和4个基本原则、6个发展目标&#xff0c;确定了8项重点任务和5项保障措施&#xff0c;进一步明确金融科技发展方向。近年来&…

ADB WIFI 链接

ADB WiFi链接手机 必须在同一网络下&#xff08;本人用的台式机网线手机连路由器WIFI&#xff09; 1.先确认USB数据线是否成功链接了手机 adb devices不管前面设备是什么名字&#xff0c;但是后面必须为device状态才算链接成功了&#xff0c;offline状态是不行的 有些没开启…

Linux Debian Jenkins快速搭建配置并运行

Jenkins安装 参考Debian Jenkins Packageshttps://pkg.origin.jenkins.io/debian-stable/ 加Key curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \/usr/share/keyrings/jenkins-keyring.asc > /dev/null 加仓库 echo deb [signed-by/u…

什么是远程工具,远程工具推荐

在当今数字化时代&#xff0c;远程工作正在变得越来越普遍。这种趋势不仅使企业管理更加便利&#xff0c;节省了时间和资源&#xff0c;同时也使员工更加自由和灵活。许多远程工作都需要使用到远程工具。本文将对远程工具进行简介和阐述。 什么是远程工具 远程工具是一种数字…

类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜

//C程序到C程序的翻译 class CCar { public: int price; void SetPrice(int p); }; void CCar::SetPrice(int p) { price p; } int main() { CCar car; car.SetPrice(20000); return 0; }struct CCar { int price; }; void SetPrice(struct CCar * this, int p) { this-&g…

【ROS】URDF:统一机器人描述格式(XML)

1、简述 统一机器人描述格式&#xff08;URDF&#xff09;是描述机器人模型的 XML 文件&#xff0c;支持Xacro&#xff08;XML宏&#xff09;&#xff0c;使用Xacro来引用已经存在的XML块&#xff0c;创建更短且可读的XML文件。 2、初始URDF描述文件 URDF描述文件为XML格式&…

测试左移-快速玩转Debug

目录 背 景 学习的意义 玩 转 Debug 一、基本介绍 二、断点设置 三、启动调试 四、调试技巧 定 位 问 题 总 结 背 景 一段代码的问题产生阶段可以分为&#xff1a;编译期和运行时 编译期的代码可以由工具&#xff08;idea、eclipse&#xff09;在程序编码过程中提示错误…

面对对象。

1.类&#xff1a; 类&#xff1a;是对象共同特征的描述。 对象&#xff1a;是真实存在的具体实例。 先设计类&#xff0c;才能创建对象并使用。 pulic class 类名{1.成员变量&#xff08;代表属性&#xff0c;一般是名词&#xff09;2.成员方法&#xff08;代表行为&#x…

达梦主备守护集群相关概念和基本原理介绍

DM数据守护一主一备或一主多备是一种集成化的高可用、高性能数据库解决方案&#xff0c;是数据库异地容灾的首选方案。通过部署 DM 数据守护&#xff0c;可以在硬件故障&#xff08;如磁盘损坏&#xff09;、自然灾害&#xff08;地震、火灾&#xff09;等极端情况下&#xff0…