指针还是学不会?跟着小代老师学,进入深入理解指针(4)

指针还是学不会?跟着小代老师学,进入深入理解指针(4)

  • 1回调函数
  • 2qsort使用举例
    • 2.1使用qsort函数排序整行数据
    • 2.2使用qsort排序结构体数据
  • 3qsort函数的模拟实现

1回调函数

回调函数就是一个通过函数指针调用的函数
如果你把函数的指针(地址)作为一个参数传递给另外一个函数,当这个指针被用来调用其所指向的函数,被调用的函数就被称为回调函数。回调函数不是有函数的实现方直接调用的,而是在特定的事件或者条件发生时候由另一方调用,用来对该事件或者条件进行相应。
深入理解指针(3)讲中我们写的计算机的实现的代码中,红⾊框中的代码是重复出现的,其中虽然执⾏计算的逻辑
是区别的,但是输⼊输出操作是冗余的,有没有办法,简化⼀些呢?
因为红⾊框中的代码,只有调⽤函数的逻辑是有差异的,我们可以把调⽤的函数的地址以参数的形式
传递过去,使⽤函数指针接收,函数指针指向什么函数就调⽤什么函数,这⾥其实使⽤的就是回调函
数的功能。

未使用回调函数前:
#include<stdio.h>
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 meun()
{printf("********************\n");printf("***1.add***2.sub****\n");printf("***3.mul***4.div****\n");printf("***   0.exit    ****\n");printf("********************\n");
}
int main()
{int x = 0;int y = 0;int input = 0;int ret = 0;do{meun();printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("请输入两个数:");scanf("%d %d",& x,& y);ret=add(x, y);printf("%d", ret);break;case 2:printf("请输入两个数:");scanf("%d %d", &x,& y);ret = sub(x, y);printf("%d", ret);break;case 3:printf("请输入两个数:");scanf("%d %d", &x,& y);ret = mul(x, y);printf("%d", ret);break;case 4:printf("请输入两个数:");scanf("%d %d",& x,& y);ret = div(x, y);printf("%d", ret);break;case 0:printf("退出计算器"); break;default: printf("输入错误,请重新输入");break;}} while (input);
}
使用回调后
#include<stdio.h>
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 cual (int(*pf)(int, int))
{int x = 0;int y = 0;printf("请输入两个数:");scanf("%d %d", &x, &y);int ret = pf(x, y);printf("%d", ret);
}
void meun()
{printf("********************\n");printf("***1.add***2.sub****\n");printf("***3.mul***4.div****\n");printf("***   0.exit    ****\n");printf("********************\n");
}
int main()
{int input = 0;do{meun();printf("请选择:");scanf("%d", &input);switch (input){case 1:cual(add);break;case 2:cual(sub);break;case 3:cual(mul);break;case 4:cual(div);break;case 0:printf("退出计算器"); break;default: printf("输入错误,请重新输入");break;}} while (input);

2qsort使用举例

让我们先了解下qsort在这里插入图片描述
在这里插入图片描述

2.1使用qsort函数排序整行数据


#include<stdio.h>
int cmp(const void* p1, const void*p2)
{return(*(int *)p1 - *(int*)p2);
}
int main()
{int arr[10] = { 3,4,7,2,5,4,3,9,2,8 };int num = sizeof(arr) / sizeof(arr[0]);qsort(arr, num, sizeof(arr[0]), cmp);for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

这边需要注意几个点,首先是qsort四个参数,最后一个参数是函数指针,指针也是地址,函数名本身就是一种地址。然后qsort默认是升序排序。

2.2使用qsort排序结构体数据

#include<stdio.h>
struct stu
{char name[20];int age;
};int cmp(const void* p1, const void*p2)
{return ((struct stu*)p1)->age - ((struct stu*)p2)->age;
}int main()
{struct stu arr[3] = { {"wang",192},{"zhang",16},{"li",18} };int num = sizeof(arr) / sizeof(arr[0]);qsort(arr, num, sizeof(arr[0]), cmp);for (int i = 0; i <3 ; i++){printf("%s,%d", arr[i].name,arr[i].age);}return 0;
}

这里总结下我出现的程序问题:
1.当我把结构体放在mian函数当中当作局部变量,编译会出现错误,当把他变为全局变量错误消失
在这里插入图片描述
在这里插入图片描述
2.我们对比下面两张部分代码
在这里插入图片描述
在这里插入图片描述
我们发现结构体强转时候需要把强转和指针变量再用括号包装一下,给的解释是结构体变量是临时的所以要再用括号包装一下啊,否则用不了。
而向int就可以直接强转。
3.还可以这样访问结构体成员
在这里插入图片描述

3qsort函数的模拟实现

使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。
注意:这⾥第⼀次使⽤ void* 的指针,讲解 void* 的作⽤。

#include<stdio.h>int comp(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}
void swap( int with,char* p1, char* p2)
{for (int i = 0; i < with; i++){char temp = *p1;*p1 = *p2;*p2 = temp;*p1++;*p2++;}
}
void my_qsort_bubble_sort(void* base, int num, int with, int (*p_com)(const void*p1, const void*p2))
{for (int i = 0; i < num - 1; i++){for (int j = 0; j < num - 1 - i; j++){if (p_com( (char*) base + j * with , (char*)base + (j + 1) * with)>0){swap(with,(char*)base + j * with, (char*)base + (j + 1) * with);}}}
}
int main()
{int arr[10] = { 2,3,45,21,4,5,9,0,3,20 };int num = sizeof(arr) / sizeof(arr[0]);int with = sizeof(arr[0]);my_qsort_bubble_sort(arr, num, with, comp);for (int i = 0; i < num; i++){printf("%d ", arr[i]);}return 0;
}

这里总结一下:当时敲完代码运行时候发现没有交换,结果检查发现是swap函数有了问题忘记给p1++,p2++了,做题关键思想是用回调函数,然后数值之间哪些要用指针来实现。

在这里插入图片描述在这里插入图片描述
这个是用模拟qsort来实现结构体排序。

#include<stdio.h>
struct stu{char name[20];int age;};
int comp(const void* p1, const void* p2)
{return ((struct stu*)p1)->age - ((struct stu*)p2)->age;
}
void swap( int with,char* p1, char* p2)
{for (int i = 0; i < with; i++){char temp = *p1;*p1 = *p2;*p2 = temp;*p1++;*p2++;}
}
void my_qsort_bubble_sort(void* base, int num, int with, int (*p_com)(const void*p1, const void*p2))
{for (int i = 0; i < num - 1; i++){for (int j = 0; j < num - 1 - i; j++){if (p_com( (char*) base + j * with , (char*)base + (j + 1) * with)>0){swap(with,(char*)base + j * with, (char*)base + (j + 1) * with);}}}
}
int main()
{struct stu  arr[] = { {"man",20},{"fyy",30},{"xyy",10} };int num = sizeof(arr) / sizeof(arr[0]);int with = sizeof(arr[0]);my_qsort_bubble_sort(arr, num, with, comp);for (int i = 0; i < num; i++){printf("%s %d ", arr[i].name,arr[i].age);printf("\n");}return 0;
}

总结一下:
当时写好结构体时候,怎么找结构体成员都找不到,结果发现自己强转错误了。这里要注意下,我们强转时候一定要明白我们比较的类型是什么。
在这里插入图片描述

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

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

相关文章

I2C通信外设

I2C外设介绍 主机&#xff0c;就是拥有主动控制总线的权利。从机&#xff0c;只能在从机允许的情况下&#xff0c;才能控制总线。 多主机模型可分为固定多主机和可变多主机。固定多主机就是总线上&#xff0c;有2个或2个以上固定的主机&#xff0c;上面固定为主机&#xff0c;下…

【Unity | Editor强化工具】资产快速访问工具

经常在Project窗口中翻找资产相对麻烦&#xff0c;Unity自带的Favorite功能又和Project窗口强绑定&#xff0c;且只能在双列视图下使用&#xff0c;故制作了一个可以在独立窗口中列举常用资产的小工具&#xff1a; Unity Asset Quick Access 。 CSDN弄了个Github加速计划&…

教你申请永久免费的 us.kg 域名 支持接入 Cloudflare

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 之前的永久免费域名 eu.org 已经很久没有审批新的域名了&#xff0c;今天给大家推荐的 us.kg 不需要审批&#xff0c;注册账号申请域名后直接可以使用&#xff0c;并且它也可以像 eu.org 一样接入 Cloudfl…

联合(union)和枚举(enum)学习(c语言)

前言 Hello,亲爱的小伙伴们&#xff0c;好久不见&#xff0c;今天我们继续来学习新的内容-----联合和枚举 如果喜欢作者菌的文章的话&#xff0c;就不要吝啬手中的三连呀&#xff0c;万分感谢&#xff01;&#xff01; 联合&#xff08;共用体&#xff09;&#xff08;union&…

【计算机网络】计算机网络的组成与功能

计算机网络的组成与功能 导读一、计算机网络的组成1.1 从组成方式上1.1.1 硬件1.1.2 软件1.1.3 协议 1.2 从工作方式上1.3 从功能组成上 二、计算机网络的功能2.1 数据通信2.2 资源共享2.3 分布式处理2.4 提高可靠性2.5 负载均衡2.6 其它 结语 导读 大家好&#xff0c;很高兴又…

Web3开发框架分析

Web3开发框架旨在简化区块链和去中心化应用&#xff08;DApp&#xff09;的开发过程&#xff0c;为开发者提供必要的工具和库。以下是一些主要的Web3开发框架。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Truffle Suite Truffl…

$MPC 登录MEXC,加速Partisia Blockchain 生态市场进程

Partisia Blockchain是一个以MPC技术方案为基础&#xff0c;具备可审计特性的隐私Layer1生态&#xff0c;与此同时&#xff0c;该链通过系列创新的系统架构&#xff0c;能够兼顾高迸发、安全、可拓展性以及可互操作特性。基于系列技术特性&#xff0c;Partisia Blockchain正在构…

OrangePi KunPengPro | linux系统下挂载U盘

OrangePi KunPengPro | linux系统下挂载U盘 时间&#xff1a;2024年6月6日21:32:53 文章目录 OrangePi KunPengPro | linux系统下挂载U盘1.参考2.操作fdisk -l 列出系统上所有磁盘的分区表信息将 /dev/sda1 分区挂载到 /mnt/udisk/ 目录显示文件系统的磁盘空间使用情况卸载文件…

RAG检索增强生成(1)-大语言模型的外挂数据库

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks Lewis P, Perez E, Piktus A, et al. Retrieval-augmented generation for knowledge-intensive nlp tasks[J]. Advances in Neural Information Processing Systems, 2020, 33: 9459-9474. RAG结合了信息检…

C++入门 ros服务通信

一、 开发环境 ubuntu20.04 ros版本noetic 参考视频 https://www.bilibili.com/video/BV1Ci4y1L7ZZ/?p52&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source4cd1b6f268e2a29a11bea5d2568836ee 二、 编写srv文件 在功能包下面创建srv文件夹…

【SpringBoot + Vue 尚庭公寓实战】项目初始化准备(二)

尚庭公寓SpringBoot Vue 项目实战】项目初始化准备&#xff08;二&#xff09; 文章目录 尚庭公寓SpringBoot Vue 项目实战】项目初始化准备&#xff08;二&#xff09;1、导入数据库2、创建工程3、项目初始配置3.1、SpringBoot依赖配置3.2、创建application.yml文件3.3、创建…

【Linux取经路】网络套接字编程——TCP篇

文章目录 前言十、Tcp Server 端代码10.1 socket、bind10.1 listen——监听一个套接字10.2 accept——获取一个新连接10.3 read——从套接字中读取数据10.4 write——向套接字中进行写入10.5 Tcp Service 端完整代码&#xff08;单进程版&#xff09;10.6 Tcp Server 端代码&am…

这个世界,对于心态好的人,就是个大游乐场,越刺激越好玩。对于胆小鬼,那就是地狱,随时随地都会受伤

心态决定你的世界&#xff1a;游乐场还是地狱 在这个充满变数的世界里&#xff0c;我们的心态决定了我们看待世界的方式。对于心态积极的人来说&#xff0c;世界就像一个巨大的游乐场&#xff0c;每一个挑战都是一个新的游戏&#xff0c;每一个刺激都是乐趣的一部分。而对于那…

解决跨域的几种方法

解决跨域的方法主要有以下几种&#xff1a; 1.CORS&#xff08;跨域资源共享&#xff09; CORS是一种W3C规范&#xff0c;它定义了一种浏览器和服务器交互的方式来确定是否允许跨源请求。 服务器通过设置响应头Access-Control-Allow-Origin来允许或拒绝跨域请求。例如&#xf…

[笔试训练](三十四)100:[NOIP2008]ISBN号码101:kotori和迷宫102:矩阵最长递增路径

目录 100:[NOIP2008]ISBN号码 101:kotori和迷宫 102:矩阵最长递增路径 100:[NOIP2008]ISBN号码 题目链接:[NOIP2008]ISBN号码_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 题解: 简单模拟 #include <iostream> #include<string> using namespace std; str…

5-Django项目--分页与搜索(资产页面)

目录 views/asset_data.py asset_data/asset_data.html 搜索与分页笔记: 搜索 整数搜索 字符串搜索 分页 views/asset_data.py # -*- coding:utf-8 -*- from django.shortcuts import render, redirect, HttpResponse from django.utils.safestring import mark_safe f…

电子元器件采购商城的售后服务保障

电子元器件采购商城的售后服务保障是用户在采购电子元器件时的重要考量因素之一。以下是常见的售后服务保障内容&#xff1a; 退换货政策&#xff1a; 质量问题退换货&#xff1a;如果用户收到的元器件存在质量问题&#xff0c;通常可以在一定时间内申请退换货。无理由退换货&a…

数据分析第一天(pandas简单的对快餐店数据进行操作获得想要的信息,使用apply,groupby)

前言 数据保存在 https://github.com/harkbox/DataAnalyseStudy 数据名称&#xff1a;快餐数据.tsv &#xff08;tsv是用\t作为字符分隔符的文件格式&#xff1b;csv是逗号&#xff09; 因此可以用pandas的read_csv函数读取数据 1.读取数据 import pandas as pd import matp…

PCA算法

PCA算法 原创 小王搬运工 时序课堂 2024-06-06 19:16 四川 1. PCA算法 PCA算法称为主成分分析&#xff0c;是一种无监督学习算法&#xff0c;主要用于数据降维和特征提取。 PCA是一种数据降维模型&#xff0c;它的基本模型是通过线性变换将数据转换到新的空间&#xff0c;这…

windows架设NTP时间服务器进行时间同步

一、windows架设NTP时间服务器 1.win11更改注册表 winR输入regedit 2.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config&#xff0c;找到Config目录&#xff0c;双击Config目录下的AnnounceFlags&#xff0c;设为5。 3.HKEY_LOCAL_MACHINE\SYSTEM\Current…