【C语言进阶】一文速通面试中的指针相关疑难杂症(内含模拟库函数 qsort 的实现)

news2024/11/23 18:41:56

目录

🥇前言🥇:

一、指向函数指针数组的指针🤯:

        1.书写格式🦚:

        2.指向函数指针数组指针示例🦩:

二、回调函数🧐:

        1.回调函数的定义🦜:

        2.回调函数使用实例🐤:

        3.使用回调函数模拟库函数 qsort 的实现🦢:

三、总结🥳:


🛰️博客主页:✈️努力学习的銮同学

🛰️欢迎关注:👍点赞🙌收藏✍️留言

🛰️系列专栏:💐【进阶】C语言学习

        家人们更新不易,你们的👍点赞👍和👉关注👈真的对我真重要,各位路过的友友麻烦多多点赞关注,欢迎你们的私信提问,感谢你们的转发!

        关注我,关注我,关注我,你们将会看到更多的优质内容!!!


🏡🏡本文重点 🏡🏡

🚅指函数指针数组指针🚃回调函数🚏🚏

🥇前言🥇:

        面试一直是所有新晋程序员们的噩梦,为了通过面试,拿到一份令自己满意的offer,所有人都在不断寻找突破点。前面我们已经对我们的指针进行了相当程度的优化,本文我将带领大家对指针的使用进行最终的剖析升级。废话不多说,我们这就开始!

一、指向函数指针数组的指针🤯:

        1.书写格式🦚:

        小伙伴们在上节课中应该对函数指针数组的认知已经比较到位了,也知道了通过函数指针数组的使用,即可以完成函数的调用,又能大幅度的提升我们代码的可读性。 

        而现在又有一个更复杂的知识,理解好这个知识点一定能够帮助我们在面试中斩杀强敌

        而它就是指向函数数组的指针,合理的使用它,将会在面试时让面对你的面试官大吃一惊。它的书写格式是这样的:

函数返回类型( * ( * 指针名 ))( 函数参数类型) = &函数名;

        2.指向函数指针数组指针示例🦩:

        下面来为大家展示面试时以及使用中我们会遇到的指向数组的指针的实际使用基础案例

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 main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	//使用函数指针从存放函数地址:
	int(*padd)(int, int) = Add(a, b);
	int(*psub)(int, int) = Sub(a, b);
	int(*pmul)(int, int) = Mul(a, b);
	//函数指针数组:
	int(*p[3])(int, int) = { padd,psub,pmul };

	//使用指针指向函数指针数组:
	//即pp为指向函数指针数组的指针
	int* pp = &p;
	
	//上面这种形式是为了便于我们理解
	//而在面试和工作中更多的会写成下面这种形式:
	int(*(*p_p))(int, int) = &p;

	//验证指向函数指针数组的指针指向是否正确:
	printf("%p\n", &p);
	printf("%p\n", pp);
	printf("%p\n", p_p);

	return 0;
}

二、回调函数🧐:

        1.回调函数的定义🦜:

        我们前面都知道了,函数的调用除了我们最基础的调用方式之外,通过函数指针我们也可以实现对函数的调用。而这种通过函数指针调用函数的方式,就称为回调函数

        在实际的使用中,如果你把函数的地址(即使用指针)传递给另一个函数 ,且当这个指针调用了它指向的函数时我们就把这样的使用方式称作回调函数。

        2.回调函数使用实例🐤:

        我们一起来看一个回调函数的基础使用实例:

//函数1:
//函数1使用了这样的调用方式,就被称为回调函数
void test()
{
	printf("test\n");
}

//函数2:
//使用函数指针接收,并对函数test进行调用:
void TEST(void(*p)())
{
	//使用函数指指针调用test函数:
	p();

	printf("TEST\n");
}

int main()
{
	//将函数地址传递给另一个函数:
	TEST(test);

	return 0;
}

        在这个过程中,函数 test 就被作为函数参数传递了出去,并且在函数 TEST 中被函数指针接收,且该指针调用了它指向的 test 函数,于是我们就可以说 test 函数是回调函数

        结合我们之前写的三个算数函数我们再来看一看回调函数在实际使用中的真实使用方式

//计算函数功能实现:
void Add(int x, int y)
{
	int z = x + y;
	printf("%d + %d = %d\n", x, y, z);
}
void Sub(int x, int y)
{
	int z = x - y;
	printf("%d - %d = %d\n", x, y, z);
}
void Mul(int x, int y)
{
	int z = x * y;
	printf("%d * %d = %d\n", x, y, z);
}

//使用函数指针调用函数:
void calc(void(*p)(int, int))
{
	int x = 0;
	int y = 0;
	printf("请输入两个操作数:>");
	scanf("%d %d", &x, &y);
	p(x, y);
}

void menu()
{
	printf("********************\n");
	printf("*****   1.ADD  *****\n");
	printf("*****   2.SUB  *****\n");
	printf("*****   3.MUL  *****\n");
	printf("*****  0.EXIT  *****\n");
	printf("********************\n");
	printf("请输入:");
}

int main()
{
	int input;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			calc(Add);
			break;
		case 2:
			calc(Sub);
			break;
		case 3:
			calc(Mul);
			break;
		default:
			break;
		}
	} while (input);

	return 0;
}

        3.使用回调函数模拟库函数 qsort 的实现🦢:

        库函数 qsort 是基于快速排序法实现的一个排序函数。而通过上面的学习,我们甚至可以通过使用回调函数来模拟出库函数 qsort 的功能实现:(注:这里我们的模拟实现方式采用冒泡方式

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;
}

三、总结🥳:

        今天我们算是给我们的指针升级之路画上了一个完美的句号,至此我们关于指针的进阶内容就全面结束了。不知道各位小伙伴们学到了多少呢🤓?有志者,事竟成,百二秦川终属楚,三千越甲可吞吴,坚持学习,不断进取,美好的明天一定在等着大家!!!小伙伴们我们下节课再见吧!💕💕💕

        🔥🔥记住曾经辱骂你的人,忘记让你委屈的事,你要为你的梦想坚持,坚持为你的梦想奋斗!!!🔥🔥

         创作不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~  你们的点赞和关注对我真的很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

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

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

相关文章

嵌入式软件工程师技能树——应用编程/网络编程/驱动开发/操作系统/计算机网络

文章目录Linux驱动开发1、Linux内核组成2、用户空间与内核的通讯方式有哪些&#xff1f;3、系统调用read/write流程4、内核态用户态的区别5、bootloader内核 根文件的关系6、BootLoader的作用7、BootLoader两个启动阶段1、汇编实现&#xff0c;完成依赖于CPU体系架构的设置&…

Win10安装Linux虚拟机-安装与使用

Win10安装Linux虚拟机-安装与使用 1、VMware 的下载 VMWare虚拟机软件是一个“虚拟PC”软件&#xff0c;它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。 下载地址&#xff1a;https://customerconnect.vmware.com/en/downloads/#all_products 在搜索中…

用 Charles 断点调试 HTTPS 请求,原理解析

现在的网站基本都是 https 的&#xff0c;而 charles 是常用的 http 抓包工具&#xff0c;所以用 charles 调试 https 请求是常见的需求。 今天就分享下如何用 charles 调试 https 请求&#xff0c;如何打断点。 首先安装 charles&#xff0c;点击 start recording&#xff1…

FineReport平台数据分析-图表显示部分系列接口

1. 概述 1.1 应用场景 当图表系列较多时&#xff0c;用户希望可以自己设置哪些系列显示&#xff0c;哪些系列不显示。以决策报表为例&#xff0c;实现效果如下图&#xff1a; 1.2 实现思路 通过FR.Chart.WebUtils.getChart("chartID").getChartWithIndex(chartInde…

静态HTML旅行主题网页作业——青岛民俗7页html+css+javascript+jquery 地方民俗网页设计与实现

&#x1f468;‍&#x1f393;静态网站的编写主要是用 HTML DⅣV CSSJS等来完成页面的排版设计&#x1f469;‍&#x1f393;&#xff0c;一般的网页作业需要融入以下知识点&#xff1a;div布局、浮动定位、高级css、表格、表单及验证、js轮播图、音频视频Fash的应用、uli、下拉…

web开发:linux常用命令总结

1.关于目录操作&#xff1a; &#xff08;1&#xff09;ls 列出当前目录下都有哪些文件/目录 也可以写成&#xff1a; ls 指定目录 列出指定目录下的文件/目录 还可以写成 ls -l 指定目录 以列表的形式列出 或缩写成 ll 指定目录 &#xff08;2&#xff09;pwd 查看当前…

shared_ptr

先看源码 template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> {template<typename... _Args>using _Constructible typename enable_if<is_constructible<__shared_ptr<_Tp>, _Args...>::value>::type;template<ty…

【TuyaOS开发之旅】环境搭建

前言 涂鸦最近更新了打磨良久的TuyaOS&#xff0c;整体使用感受非常的nice。所以决定写一个专栏讲解一下TuyaOS的入门使用&#xff0c;来方便小白快速的入门和熟悉TuyaOS的开发。 官方环境搭建教程 Tuya Wind IDE-TuyaOS-涂鸦开发者 报错和解决 暂无 补充 程序下载方法 …

MetaFormer实际上是你所需要的视觉

transformer在计算机视觉任务中显示出了巨大的潜力。人们普遍认为&#xff0c;他们基于注意力的token混合器模块对他们的能力贡献最大。然而&#xff0c;最近的工作表明&#xff0c;transformer中基于注意力的模块可以被空间mlp取代&#xff0c;得到的模型仍然表现相当好。基于…

11.关联容器

文章目录关联容器11.1使用关联容器使用map使用set11.2关联容器概述11.2.1定义关联容器初始化multimap或multiset11.2.2关键字类型的要求有序容器的关键字类型使用关键字类型的比较函数11.2.3pair类型创建pair对象的函数11.3关联容器操作11.3.1关联容器迭代器set的迭代器是const…

为什么Docker比VM虚拟机快?

(1)docker有着比虚拟机更少的抽象层 由于docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化&#xff0c;运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。 (2)docker利用的是宿主机的内核,而不需要加载操…

基于springboot招生管理系统设计与实现的源码+文档

摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括招生管理系统的网络应用&#xff0c;在外国招生管理系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。招生管理系统具有招生公告信息管理功能…

实训任务一

文章目录实训任务一一、实训任务1、创建并且配置三个虚拟机2、创建SSH连接3、实现IP地址与主机名的映射4、关闭和禁用防火墙5、创建目录结构6、压缩打包7、安装软件包8、创建脚本文件9、直接运行脚本10、虚拟机相互免密登录11、远程拷贝文件实训任务一 需求&#xff1a;熟练掌…

java+MySQL 基于ssm高校创新实践学分认定系统

随着现代实践学分认定的快速发展,可以说实践学分认定已经逐渐成为现代实践学分认定过程中最为重要的部分之一。但是一直以来我国传统的实践学分认定并没有建立一套完善的行之有效的实践学分认定系统,传统的实践学分认定已经无法适应高速发展,无论是从效率还是从效果来看都远远的…

问题解决之:chatGPT 登录页面的 google 验证 reCAPTCHA 弹不出来

文章目录问题描述自己的境况分析结论问题描述 今天我到了图书馆想访问一下 chatgpt&#xff0c;挂了 vpn 之后所有的浏览器都无法弹出 reCAPTCHA 人机验证&#xff0c;即使我更换了不同的 vpn 和为 chrome 的 reCAPTCHA 设置了重定向也无法成功 正常情况&#xff1a;应该弹…

基于B\S的《C语言程序设计》学习网站的设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 1)系统平面设计&#xff1a;设计精美、简洁且清爽的系统界面。 2)课程信息管理&#xff1a;对课程的基本信息、课程目标…

Mybatis源码分析(二)Mybatis-config.xml的初始化

目录一 环境搭建二 配置文件初始化2.1 ClassLoader2.2 获取配置文件官网&#xff1a;mybatis – MyBatis 3 | 简介 参考书籍&#xff1a;《通用源码阅读指导书&#xff1a;MyBatis源码详解》 易哥 参考文章&#xff1a; 一看你就懂&#xff0c;超详细java中的ClassLoader详解A…

【Unity3DRPG入门学习笔记第三卷】PolyBrush 构建场景

一、安装 Polybrush 导入样例 我新建了一个新文件夹 Plugins 用来管理 打开 Polybrush Window 二、使用 Polybrush 1. 选中物体&#xff0c;使用第一个工具&#xff0c;会发现可以显示顶点&#xff0c;可以改变网格&#xff0c;例如我们可以上下拖拽地面改变地形 正常左键点…

Java 包装类

Java包装类\huge{Java \space 包装类}Java 包装类 概述 所谓的包装类&#xff0c;通俗来讲其实就是888种基本数据类型对应的引用类型&#xff08;本质就是引用类型&#xff09;。 ❗❗❗尤其注意charcharchar对应的包装类的名称是charactercharactercharacter&#xff0c;in…

大数据学习:shell基础

文章目录一、常用shell命令任务一&#xff1a;查看/etc目录信息前5行信息任务二&#xff1a;查看/etc/profile文件后5行信息二、grep命令选项参数任务一&#xff1a;抓取/etc目录下的python信息任务二&#xff1a;抓取/etc/profile文件里的dev信息任务三&#xff1a;抓取用户数…