深入理解c指针(七)

目录

十、回调函数和qsort函数

1、回调函数

2、简单介绍size_t 数据类型

3、qsort 排序函数 

3.1 qsort函数简单举例1(升序排序)

3.2 qsort函数简单举例2(字符串长度排序)

3.3 简单讲解 -> 操作符

3.4 常见符号的ASCII码值

3.5 简单介绍strcmp函数 

3.6 使用qsort排序结构数据

4、qsort函数的模拟实现(利用冒泡排序算法)


十、回调函数和qsort函数

ps:关于函数指针的内容在深入理解c指针(六)

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_s("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}
int main()
{int input = 1;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("请选择:");scanf_s("%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、简单介绍size_t 数据类型

   size_t 与int 、double一样是C语言中的一种数据类型,通常用于表示对象的大小(以字节为单位)或数组的索引。它是无符号整数类型,在不同的系统上的大小可能会有所不同,但通常被定义为能够容纳系统中最大对象大小的无符号整数类型。字节大小如下:

3、qsort 排序函数 

        在C语言中,qsort函数是stdlib.h标准库中的一个函数,用于对任意数据类型进行快速排序。qsort函数的原型如下:

  • base:指向要排序的数组的指针,接收数组首元素地址。
  • nmemb:数组中元素的个数。
  • size:数组中每个元素的大小(以字节为单位)。
  • compar:指向比较函数的指针,用于指定元素之间的比较规则。(函数指针)

        比较函数compar接受两个指向元素的指针,返回一个整数值来指示这两个元素的大小关系。如果返回值是负数,则表示第一个元素应该排在第二个元素之前;如果返回值是正数,则表示第二个元素应该排在第一个元素之前;如果返回值是零,则表示两个元素相等。

3.1 qsort函数简单举例1(升序排序)

3.2 qsort函数简单举例2(字符串长度排序)

       当我们调用qsort函数时,需要传递四个参数:要排序的数组指针、数组中元素的个数、每个元素的大小以及比较函数指针。

        假设我们有一个包含字符串的数组,我们想要按照字符串长度进行排序。首先,我们需要定义一个比较函数,该函数将根据字符串的长度来比较两个字符串。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 比较函数,按字符串长度升序排序
int compare(const void *a, const void *b) 
{size_t len_a = strlen(*(char **)a);size_t len_b = strlen(*(char **)b);return len_a - len_b;
}int main() 
{char *arr[] = {"apple", "banana", "orange", "kiwi", "pear"};int n = sizeof(arr) / sizeof(arr[0]);qsort(arr, n, sizeof(char *), compare);for (int i = 0; i < n; i++) {printf("%s\n", arr[i]);}return 0;
}

        在这个例子中,我们定义了一个字符串数组arr,并且定义了一个比较函数compare,用于按照字符串长度升序排序。在比较函数中,我们使用strlen函数获取字符串的长度,并将其转换为size_t类型进行比较。

       在main函数中,我们调用qsort函数对字符串数组arr进行排序,将每个元素的大小(指向字符串的指针)作为sizeof(char *)传递给qsort函数。

3.3 简单讲解 -> 操作符

   -> 操作符,用于访问结构体和联合体类型的成员,通过指向结构体或联合体的指针进行成员访问。它通常用于简化指针访问结构体成员的操作。

       具体来说,如果有一个结构体指针ptr,需要访问它所指向的结构体中的成员变量member,可以使用ptr->member来实现,这样就可以通过指针直接访问结构体中的成员,而不需要先解引用指针再使用 .操作符。示例如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>struct Person 
{char name[20];int age;
};int main() 
{struct Person person1;struct Person *ptr = &person1;// 使用strcpy函数给name成员赋值strcpy(ptr->name, "John Doe");ptr->age = 25;// 输出成员变量name和age的值printf("Name: %s, Age: %d\n", ptr->name, ptr->age);return 0;
}

 在上面的示例中,ptr->age用于访问结构体Person中的成员变量age,而不需要通过(*ptr).age的方式来访问。

3.4 常见符号的ASCII码值

3.5 简单介绍strcmp函数 

   strcmp函数是C语言中用于比较两个字符串大小的函数,其原型定义在string.h头文件中。该函数用于按字典顺序比较两个字符串,并返回一个整数值来表示比较结果。原型如下:

int strcmp(const char *str1, const char *str2);

      函数接受两个参数,分别是指向要比较的字符串的指针str1str2。它们分别指向以null结尾的C字符串(即以null字符\0作为字符串的结束标志)。 

只要记住: 

1.这个函数比较的是两个字符串对应位置元素的ASCII码值,如果str1对应元素的ASCII码值在str2对应元素之前,则返回一个负整数,在其之后返回正整数,如果相等,则比较下一个元素。

2.该函数是对字符串元素依次进行比较,如果相等则比较下一个,一旦发现不相等的字符就能确定两个字符串的大小关系,后面的元素就不比较了。

3.如果两个字符串长度不相等,且前几个元素ASCII码值相同,那么短的比长的小。(如果短的是第一个字符串则返回负数,如果短的是第二个字符串则返回正数)

3.6 使用qsort排序结构数据
#include<stdio.h>
#include<string.h>
#include<stdlib.h>//定义Stu结构体
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;
}//比较名字的函数
int cmp_stu_by_name(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}//按照年龄来排序
void test2()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);//打印排序结果int i = 0;for (i = 0; i < sizeof(s) / sizeof(s[0]); i++){printf("Student %d:\n", i + 1);printf("Name: %s\n", s[i].name);printf("Age: %d\n", s[i].age);printf("\n");}}//按照名字来排序
void test3()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);//打印排序结果int i = 0;for (i = 0; i < sizeof(s) / sizeof(s[0]); i++){printf("Student %d:\n", i + 1);printf("Name: %s\n", s[i].name);printf("Age: %d\n", s[i].age);printf("\n");}
}int main()
{test2();test3();return 0;
}

4、qsort函数的模拟实现(利用冒泡排序算法)

ps:冒泡排序的基本思想在深入理解指针(五)

#include <stdio.h>
#include<stdlib.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(arr[j]>arr[j+1]if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){// int tmp=arr[j];// arr[j]=arr[j+1];// arr[j+1]=tmp;_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;
}

 

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

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

相关文章

如何利用会话式AI提升你的工作效率?

会话式AI如何改变我们的生活和工作 在当今时代&#xff0c;内容策略的重要性日渐凸显&#xff0c;良好的内容策略能够与流量及转化率紧密相连&#xff0c;成为企业在内容策略领域不容忽视的营销工具之一。 然而&#xff0c;目前内容同质化现象严重&#xff0c;企业若想在内容营…

iPaas数据传输的方式

一、iPaas平台概述 iPaas&#xff08;Integration Platform as a Service&#xff09;平台&#xff0c;作为一种先进的云计算服务模式&#xff0c;为开发者和企业提供了一种全面且灵活的应用集成解决方案。它构建在PaaS&#xff08;Platform as a Service&#xff09;基础之上…

【C++庖丁解牛】初始化列表 | Static对象 | 友元函数

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1. 再谈构造函数1.1 …

WiFi模块赋能智能手表:拓展功能与提升连接性

随着科技的不断进步&#xff0c;智能手表正逐渐成为现代人生活中不可或缺的智能配饰。其中&#xff0c;WiFi模块的应用为智能手表带来了更多强大的功能和更高的连接性&#xff0c;为用户提供了更为便捷、智能化的使用体验。本文将深入探讨WiFi模块在智能手表中的应用。 远程通信…

RK DVP NVP6158配置 学习

NVP6158简介 NVP6158C是一款4通道通用RX&#xff0c;提供高质量图像的芯片。它接受来自摄像机和其他视频信号的独立4通道通用输入来源。它将4通道通用1M至8M 7.5P视频格式数字化并解码为代表8位ITU-R BT.656/1120 4:2:2格式的数字分量视频&#xff0c;并将单独的BT.601格式与27…

40个Python字符串实例

Python 字符串是 Python 编程语言中最常用的数据类型之一&#xff0c;它可以表示文本或一组字符。Python 中的字符串是不可变的序列&#xff0c;意味着一旦创建&#xff0c;其值就不能被修改。下面是一些关于 Python 字符串的介绍。 概述 创建字符串&#xff1a;可以使用单引…

如何找回删除的文件?5个数据恢复方法

电脑已经成为我们生活和工作不可或缺的一部分。然而随着电脑使用频率的增加&#xff0c;误删文件的情况也时有发生。一旦重要的文件被误删&#xff0c;很多人会感到惊慌失措。实际上只要掌握了一些有效的数据恢复方法&#xff0c;就有可能找回那些被误删的文件。本文将为你介绍…

指针中的回调函数与qsort的深度理解与模拟

今天给大家在更新一下指针类型的知识&#xff0c;这里讲到了一个库函数sqort&#xff0c;以及回调函数的理解。 望喜欢 目录 回调函数 qsort函数 qsort模拟实现 回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数…

Mac清理电脑垃圾工具CleanMyMac X4.15中文免费版下载

嘿&#xff0c;亲爱的Mac用户们&#xff0c;你们是否曾经想象过你的电脑是一座美丽的城市&#xff0c;而垃圾文件则是那些不速之客&#xff0c;悄悄堆积&#xff0c;影响着城市的整体美观。今天&#xff0c;我们就来聊聊Mac为什么会产生垃圾文件&#xff0c;这些垃圾文件会对你…

【科研基础】插图摘录

FedSL: Federated Split Learning for Collaborative Healthcare Analytics on Resource-Constrained Wearable IoMT Devices Blockchain-Based Trustworthy and Efficient Hierarchical Federated Learning for UAV-Enabled IoT Networks

机械五要素手持气象站的应用

TH-SQ5在数字化和智能化的时代背景下&#xff0c;气象监测技术正日益成为众多行业不可或缺的利器。其中&#xff0c;机械五要素手持气象站以其便携性、实时性和多功能性受到了广泛关注。下面讲解一下手持气象站是什么以及应用&#xff1a; 一、机械五要素手持气象站概述 机械五…

白酒:制曲工艺的环境因素与微生物生态关系

在豪迈白酒的酿造过程中&#xff0c;制曲工艺是非常关键的一环。而环境因素与微生物生态关系对于制曲工艺的成功与否起着决定性的作用。云仓酒庄深谙此道&#xff0c;在制曲过程中注重环境因素的调控&#xff0c;并深入研究微生物生态关系&#xff0c;以提升豪迈白酒的品质和风…

【Java EE 】认识文件与Java文件操作

目录 &#x1f340;认识文件&#x1f338;树型结构组织 和 目录&#x1f338;文件路径&#xff08;Path&#xff09;&#x1f338;其他知识 &#x1f333;Java 中操作文件&#x1f338;File 概述&#x1f33b;属性&#x1f33b;构造方法&#x1f33b;方法 &#x1f338;代码示例…

【论文精读】I-JEPA

摘要 计算机视觉中&#xff0c;常采用基于不变性和基于生成的方法进行自监督学习。对比学习&#xff08;CL&#xff09;是典型的基于不变性的方法&#xff0c;通过预训练方法优化编码器&#xff0c;使其能生成同一图像的两个或多个视图的相似嵌入&#xff0c;其中图像视图通常由…

【Linux实践室】Linux常用命令

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux文件操作2.1.1 &#x1f47b;创建文件2…

【vue.js】文档解读【day 1】 | 模板语法2

如果阅读有疑问的话&#xff0c;欢迎评论或私信&#xff01;&#xff01; 本人会很热心的阐述自己的想法&#xff01;谢谢&#xff01;&#xff01;&#xff01; 文章目录 模板语法JavaScript表达式仅支持表达式调用函数&#xff1f;受限的全局访问 指令参数动态参数动态参数中…

面试题HTML+CSS+网络+浏览器篇

文章目录 Css预处理sass less是什么&#xff1f;为什么使用他们怎么转换 less 为 css&#xff1f;重绘和回流是什么http 是什么&#xff1f;有什么特点HTTP 协议和 HTTPS 区别什么是 CSRF 攻击HTML5 新增的内容有哪些Css3 新增的特性flex VS grid清除浮动的方式有哪些&#xff…

Yolov8改进交流

YOLO v8改进 YOLOv8的改进&#xff0c;我接触的主要分为网络改进和代码改进&#xff0c;网络改进就是以注意力、主干为主&#xff0c;代码改进就是类似于Iou&#xff0c;类别权重等修改。 以下是yolov8的原始模型。 # Ultralytics YOLO &#x1f680;, AGPL-3.0 license # YO…

Tensorflow2.0+部署(tensorflow/serving)过程备忘记录Windows

Tensorflow2.0部署&#xff08;tensorflow/serving&#xff09;过程备忘记录 部署思路&#xff1a;采用Tensorflow自带的serving进模型部署&#xff0c;采用容器docker 1.首先安装docker 下载地址&#xff08;下载windows版本&#xff09;&#xff1a;https://desktop.docke…

[译]BNF 表示法:深入了解 Python 的语法

[译]BNF 表示法&#xff1a;深入了解 Python 的语法 原文&#xff1a;《BNF Notation: Dive Deeper Into Python’s Grammar》 https://realpython.com/python-bnf-notation/ 在阅读Python文档的时候&#xff0c;你可能已经遇到过BNF(Backus–Naur form)表示法&#xff1a; 下…