指针进阶详解续---C语言

❤博主CSDN:啊苏要学习

  ▶专栏分类:C语言◀

  C语言的学习,是为我们今后学习其它语言打好基础,C生万物!

  开始我们的C语言之旅吧!✈

目录

前言:

一.函数指针数组

二.指向函数指针数组的指针

三.回调函数

四.学习qsort


前言:

  上一篇我们讲了函数指针,这篇是函数指针数组等更多内容,最后我们学习一下qsort的使用,加强我们对函数指针的理解。

一.函数指针数组

  整型数组,是以整型为元素的数组,类似的,函数指针数组是存放函数指针的数组

  当我们拿到函数的地址,就能通过其地址调用该函数,现将多个函数地址存到数组里,实现一个计算器:

void menu()
{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;int x = 0, y = 0, ret = 0;//第一个用NULL挤位置int(*pfarr[5])(int, int) = { NULL, Add, Sub, Mul, Div };do{menu();printf("请输入:>");scanf("%d", &input);if (input == 0){printf("退出计算器\n");break;}else if (input >= 1 && input <= 4){printf("请输入两个数:>");scanf("%d %d", &x, &y);ret = pfarr[input](x, y);printf("ret = %d\n", ret);}else{printf("输入错误,请重新输入\n");}} while (input);return 0;
}

  Add这些函数没打在代码里,读者知道即可,函数指针数组的存在,让一些代码变得很简洁。

  在以后如果需要添加新的计算方法,可以把函数指针加到数组中,改一改就可以正常使用啦。

二.指向函数指针数组的指针

  函数指针数组也是一个数组,也可以取地址,取出来的地址就可以存放到一个指针里,这个指针就叫函数指针数组的指针。

  之后的指针也可以放到数组里,就这样套娃,当然我们也不一定会用到,但我们要学,要知道,要会。

  这里我们来练习一个如何快速且正确写出类型:

int Add(int x, int y);
int main()
{//函数指针int(*pf)(int, int) = Add;//函数指针数组//1.把函数指针类型先搬下来//2.数组的话直接加[]int(*pfarr[5])(int, int) = {Add};//函数指针数组的指针//1.把函数指针数组类型搬下来//2.指针要加一颗*并用()包起来int(* (*ppfarr)[5])(int, int) = &pfarr;//注意:不能直接这样int((*ppfarr)[5])(int, int)//第一颗星是函数指针类型的 int(*)(int, int);return 0;
}

三.回调函数

  当A函数的地址作为参数传参给B函数,B函数使用这个地址调用A函数,A函数就是回调函数。
  回调函数不是实现方直接调用的,而是在特定条件发生时,由另一方调用,用来对该条件进行响应。

  函数指针的一个非常大的用途就是实现回调函数,回调函数的实现离不开函数指针的支持

void Calc(int (*pf)(int, int))
{int x = 0;int y = 0;int ret = 0;printf("请输入两个数:>");scanf("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}int main()
{int input = 0;do{menu();printf("请输入:>");scanf("%d", &input);switch (input){case 0:printf("退出计算器\n");break;case 1:Calc(Add);break;case 2:Calc(Sub);break;case 3:Calc(Mul);break;case 4:Calc(Div);break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}

  这次使用函数指针方式实现这个计算器,Calc是一个函数,它的参数是一个函数指针,这样Calc就可以具有多个函数的功能

  当我们需要Calc实现什么功能,把对应函数的地址传进去,在Calc里面到特定的时候调用,这个通过函数指针调用的函数就叫回调函数。

四.学习qsort

  q是quick的意思,qsort--快排。和以前实现的bubble_sort相比,抛开效率这一点,冒泡排序只能实现整数的排序

  而qsort可以实现任意类型数据的排序,我们先查查文档,学习了解qsort如何使用,再模拟实现。

  qsort是排序被base指向的数组里的num个元素,每个元素大小为size,比较的方法通过函数指针传参进去。

  compar比较,p1是数组里a元素的地址,p2是数组里b元素的地址,如果p1指向的元素大于p2指向的,返回大于0的数;以及另外两种情况。

  void*是无类型的指针,它可以接收任意数据类型的地址,但是不能对它解引用或指针加减运算,可以先强制类型转换再使用

  base数组和cmp参数设置成void*的目的是让函数能够具有普遍性

使用者可能传一个整型数组,也可能传一个浮点型数组,比较的元素也可能是不确定的,设置成空类型,就都可以接收而不会报警告。

  对结构体中的字符串进行比较,上图是还未排序前的顺序,根据字母ASCII码值的大小排序应是:fa->hong->li->san

  好啦,qsort如何使用也学完了,我们下篇就使用冒泡排序代替快速排序模拟实现一个可以排序任意类型的bsort

结语:希望读者读完有所收获!在学C的路上,祝福我们能越来越C!✔

  读者对本文不理解的地方,或是发现文章在内容上有误等,请在下方评论区留言告诉博主哟~,也可以对博主提出一些文章改进的建议,感激不尽!最后的最后!

  ❤求点赞,求关注,你的点赞是我更新的动力,一起努力进步吧。

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

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

相关文章

Linux系统部署Python语言开发运行环境

目录 Ubuntu自带python Debian安装python 安装 pip 库列表 安装第三方库 使用国内镜像站 实装 tkinter 库 编写运行代码 测试代码1 1. 创建项目 2. 创建源码文件 3. 写入源代码 4. 修改权限 5. 运行代码 测试代码2 本文的使用环境是Windows的Linux 子系统&…

微前端中的 CSS

本文为翻译 本文译者为 360 奇舞团前端开发工程师原文标题&#xff1a;CSS in Micro Frontends 原文作者&#xff1a;Florian Rappl 原文地址&#xff1a;https://dev.to/florianrappl/css-in-micro-frontends-4jai 我被问得最多的问题之一是如何在微前端中处理 CSS。毕竟&…

键入网址到网页显示,期间发生了什么

HTTP 浏览器做的第一步工作是解析URL 首先浏览器做的第一步工作就是要对URL进行解析&#xff0c;从而生成发送给 web 服务器的请求信息。 所以图中长长的URL实际上是请求服务器里的文件资源。 如果图中的蓝色部分URL元素省略了&#xff0c;那应该请求哪个文件呢&#xff1f; 当…

HTML5注册页面

分析 注册界面实际上是一个表格&#xff08;对齐&#xff09;&#xff0c;一行有两个单元格。 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevic…

Linux:在使用UEFI固件的计算机上内核是如何被启动的

前言 启动计算机通常不是一件难事&#xff1a;按下电源键&#xff0c;稍等片刻&#xff0c;你就能看到一个登录界面&#xff0c;再输入正确的密码&#xff0c;就可以开启一天的网上冲浪之旅了。 但偶尔这件事没那么顺利&#xff0c;有时候迎接你的不是熟悉的登录界面&#xf…

java 数组的使用

数组 基本介绍 数组可以存放多个同一类型的数据&#xff0c;数组也是一种数据类型&#xff0c;是引用类型。 即&#xff1a;数组就是一组数据。 数组的使用 1、数组的定义 方法一 -> 单独声明 数据类型[] 数组名 new 数据类型[大小] 说明&#xff1a;int[] a new int…

上海亚商投顾:沪指震荡微涨 金融、地产午后大幅走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 三大指数早盘震荡&#xff0c;午后集体拉升反弹&#xff0c;创业板指涨超1%。券商等大金融板块午后再度走强&#…

学习线性表:掌握基本操作和应用

线性表 前言 欢迎来到本博客的线性表部分&#xff01;&#x1f604;&#x1f389;在这篇博文中&#xff0c;我将带您深入探索数据结构中的线性表&#xff0c;这是计算机科学中最基础也是最重要的数据结构之一。 线性表是一种线性数据结构&#xff0c;它由一组连续的元素组成…

socket server服务器开发常见的并发模型

两种高效的事件处理模式 服务器程序通常需要处理三类事件&#xff1a;I/O 事件、信号及定时事件。有两种高效的事件处理模式&#xff1a;Reactor和 Proactor&#xff0c;同步 I/O 模型通常用于实现Reactor 模式&#xff0c;异步 I/O 模型通常用于实现 Proactor 模式。 无论是 …

Flink开发环境准备: centos-jdk8

linux-jdk8 - Flink开发环境准备 一、基本介绍二、环境准备1.1 JDK环境1.2 开发工具1.3 Maven环境 三、flink下载安装配置3.1 Flink下载3.2 flink本地模式安装 - linux3.3 常用配置3.4 日志的查看和配置 四、单机 Standalone 的方式运行 Flink 一、基本介绍 Flink底层源码是基于…

python+django+mysql项目实践二(前端及数据库)

python项目实践 环境说明&#xff1a; Pycharm 开发环境 Django 前端 MySQL 数据库 Navicat 数据库管理 前端模板 添加模板 在templates下创建 views文件中添加 创建数据库 连接数据库 在setting文件中进行配置 创建表

Redis持久化机制

AOF 把对redis的写操作记录下来&#xff0c;先执行命令&#xff0c;再执行写入&#xff0c;优势在于&#xff1a; 当然也有风险&#xff1a;丢失和对下一个命令造成阻塞 丢失的原因是执行写操作和记录日志是两个过程 下一个命令造成阻塞的原因是两个过程是同步的 第二个问…

python GUI nicegui初识一(登录界面创建)

最近尝试了python的nicegui库&#xff0c;虽然可能也有一些不足&#xff0c;但个人感觉对于想要开发不过对ui设计感到很麻烦的人来说是很友好的了&#xff0c;毕竟nicegui可以利用TailwindCSS和Quasar进行ui开发&#xff0c;并且也支持定制自己的css样式。 这里记录一下自己利…

【在英伟达nvidia的jetson-orin-nx上使用调试can基础收发-硬件连接-开机自启动can-初步调试】

【在英伟达nvidia的jetson-orin-nx上使用调试can基础收发-硬件连接-开机自启动can-初步调试】 1、概述2、实验环境3、自我学习4-1、实验过程1、硬件原理图焊接连接模块2、输入命令3、测试过程 4-2、目前遗留问题# 1-1、发送可以发送&#xff0c;但是PC发送数据收不到。# 1-2、接…

Maven项目中Lifecycle和Plugins下的install的区别

在Maven中&#xff0c;如果你的web和service在不同的模块下&#xff0c;如果直接用用tomcat插件运行web层&#xff0c;那么运行时会报错 Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.5.2:install (default-cli) on project springboot: The pack…

ResNet-残差网络二

文章目录 残差结构的一般表达形式残差结构中的信息传播clean path propagation前向传播反向传播 h(x)为恒等映射的重要性h(x)的实验证明 激活层的位置 和其他网络的对比 上一篇讲了 ResNet 论文中的第一篇&#xff1a;Deep Residual Learning for Image Recognition&#xff0c…

每日一题——反转单链表

反转单链表 题目链接 下面主要介绍两种方法&#xff1a; 方法一&#xff1a; 利用三个指针变量进行反转 具体过程如图所示&#xff1a; 注意&#xff1a;循环的结束的条件为cur NULL而不是next NULL 实现代码&#xff1a; struct ListNode* reverseList(struct ListNode* …

【C++】——内存管理

目录 回忆C语言内存管理C内存管理方式new deleteoperator new与operator delete函数new和delete的实现原理定位new表达式(placement-new)malloc/free和new/delete的区别 回忆C语言内存管理 void Test() {int* p1 (int*)malloc(sizeof(int));free(p1);int* p2 (int*)calloc(4…

解决Linux下PyCharm无法新建文件

一、问题描述 如图&#xff0c;在Ubuntu Linux系统中使用pycharm管理项目时&#xff0c;提示无法新建.py源文件&#xff1a; 二、问题解决 将问题定性为文件夹&#xff08;目录&#xff09;权限问题&#xff0c;在终端中打开项目文件夹的上级目录&#xff0c;将整个项目目录的…

mysql按照日期分组统计数据

目录 前言按天统计按周统计按月统计按年统计date_format参数 前言 mysql的date_format函数想必大家都使用过吧&#xff0c;一般用于日期时间转化 # 例如 select DATE_FORMAT(2023-01-01 08:30:50,%Y-%m-%d %H:%i:%s) # 可以得出 2023-01-01 08:30:50# 或者是 select DATE_FOR…