C语言易错知识点十(指针(the final))

❀❀❀ 文章由@不准备秃的大伟原创 ❀❀❀

♪♪♪ 若有转载,请联系博主哦~ ♪♪♪

❤❤❤ 致力学好编程的宝藏博主,代码兴国!❤❤❤

        许久不见,甚是想念,真的是时间时间,你慢些吧,不能再让头发变秃了 ,我愿用我一生换我头发常青~~(^▽^ )。好的好的,今天是12月31号,是2023年的最后一天,博主这里提前祝大家新年快乐!

9c86da63099546dea3b0e2bba7e19a07.gif

        最后一天了, 博主在这里问各位铁汁们一句:“2022年定下的目标2023年都实现了吗?2023又要为2024定什么目标呢?” 或许有些铁汁会骄傲的拍拍胸脯说:“何止实现了,我还超了呢!”,或许也有铁汁会说:“嗐,2023年因为这样那样的原因,没有能完成去年定的目标,很后悔!”

        其实无论你是处在哪种阶段,博主只想说:“向前看吧,过去的已经不存在了,过去一年里你是荣华富贵或是灰头土脸又如何,难道以后就不会改变了吗?就像我们头上的头发,终有一天也会变白,脱落,但是生活不还得继续吗?所以,抛下顾虑,放下过去的荣辱,在新的一年里继续努力,为更好的未来而前进吧!

         鸡汤虽多,但不喝也无用。所以,为了更好的未来,我们铁汁们还是需要继续学习的是吧,还会继续给大伟点赞收藏,继续支持大伟的对吧~对吧~对吧~ヾ(≧▽≦*)o

        呃哼,我们今天来看看C语言的核心:指针的最后一篇。今天我们要学的知识是:没了。

        8ee9a4163de74335adec0d01f38448fc.png

        啊不是,应该是有关指针的内容基本没了,这一篇主要是一些扩展,别误解哦~  好的,今天要学的内容是:回调函数,qsort使用和模拟实现,最后是有关指针的笔试题。

        诶,但是在开始之前,我们先谈一谈上一篇博客最后提到的两段代码,什么,不记得了?哼,就知道会发生这种情况,快去看—————>指针(part three)

        一.

(*(void (*)())0)();

       大家整体看这段代码是不是难于理解?那如果我们把它分为几个区块,从内部一个一个分析呢?:

void (*)()

  这是一个函数指针的声明。它声明了一个指向不带参数(void)并返回 void 的函数的指针

(void (*)())0

   这是将整数 0 转换为指定类型的函数指针

(*(void (*)())0)

   这对函数指针进行了解引用。它将地址为 0 的值视为函数并调用它

         简单来说,这段代码试图调用内存地址为 0 处的函数

        怎么说,铁汁们,从内部一步一步分解是不是就会相对好理解了?里面的内容其实是我们已经学过的知识的集合体啊,对不对。

        二.那么根据以上的思路,兄弟们自己再试图理解理解下面这个代码:

 void (*signal(int , void(*)(int)))(int);

  ——————————————————————————————————————————

signal

这是一个函数名

int

 这是signal函数的第一个参数,表示信号编号

void(*)(int)

 这是signal函数的第二个参数,是一个函数指针。它表示指向一个接受int参数并返回void的函数的指针。这个函数指针是信号处理函数,指定了在接收到信号时应采取的操作

(*signal(int, void(*)(int)))

 这部分表示signal是一个接受两个参数并返回某种结果的函数。声明的最外层指定了返回的类型

void(*)(int)

 这指定了signal函数的返回类型。它是一个函数指针,指向一个接受int参数并返回void的函数。这与signal返回信号处理函数的函数指针的概念一致

         综合起来,signal函数接受两个参数:一个表示信号编号的int,一个表示信号处理函数的函数指针。它返回一个类型为void (*)(int)的函数指针

        OK,这里把上一篇博客遗留下的问题解决了,现在开始这次的内容:

                回调函数

        定义:回调函数就是⼀个通过函数指针调⽤的函数

简单来说:就是在函数内定义了另一个函数 ,如:

int add(int a, int b)
{return a + b;
}
void calc(int(*pf)(int, int))
{int ret = 0;int x, y;printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}
int main()
{
calc(add);
return 0;
}

        calc函数接受一个函数指针 pf,该指针指向一个接受两个整数参数并返回整数的函数。

               qsort使用及实现

        以下是qsort函数的使用演示:

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数
int int_cmp(const void * p1, const void * p2)
{return (*( int *)p1 - *(int *) p2);
}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++){printf("%d ", arr[i]);}return 0;
}

        以下是cpp官方给的qsort的解释:ea6524a5d25b4d25a942e4658316bf5e.png         其中的四个元素:cf4a231fb83545b6a30949a9cd98eaee.png

        还是那句话,虽然我们程序猿不需要多好的英语,但是我们以后是需要看各种英文的文献的,所以我们从现在开始就要逐渐适应读英文的文章。

        简单来说:qsort函数内部第一个元素:要排序的数组名,第二个元素:数组的大小,第三个元素:数组内存储的类型的字节大小,第四个元素:一个cmp函数,函数内实现的是两个指针的对比。(如上,*a -*b为升序,*b - *a 为降序,*a > *b 为升序,*a < *b 为降序)

        拓展一下:qsort库函数底层是快排,时间复杂度是O(N*logN) ,在我们刷题的时候还蛮经常用的。

        那现在我们来对qsort函数进行个模拟实现,当然,是以冒泡的方法,所以时间复杂度是O(N*N)。那我们来看看吧!:

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

        这个模拟实现是完全按照官方给的元素来写的,浓度比较高,大家好好吸收哦~

                   指针笔试题

        其实的话到这里有关指针的内容已经可以结束了,但是呢,学而不思则罔,学会了,还需要大量的练习,正如前段时间网上比较火的:9f9270086a3544da8920f0e845e01aee.png        

        题目是做不完的,但是知识点是固定的,博主这里给大家出三道题,大家珍惜哦~

        一. 

int main()
{int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int *ptr1 = (int *)(&aa + 1);int *ptr2 = (int *)(*(aa + 1));printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));return 0;
}

        解析:&aa+1越过了整个二维数组aa,所以ptr1指向的是二维数组后面的那个元素,然后ptr-1,指向的是10;而aa+1越过了整个二维数组的第一行,ptr2指向的是6,ptr2-1指向的是aa第一行的最后一个元素5。

        答案就是10和5

        二.

int main()
{char *a[] = {"work","at","alibaba"};char**pa = a;pa++;printf("%s\n", *pa);return 0;
}

        定义了一个指针数组*a[],又定义了一个二级pa指向a的首元素“work”,pa++也就是a向后走一个元素,此时*pa就是“at”。

        答案就是at

        三.

int main()
{char *c[] = {"ENTER","NEW","POINT","FIRST"};char**cp[] = {c+3,c+2,c+1,c};char***cpp = cp;printf("%s\n", **++cpp);printf("%s\n", *--*++cpp+3);printf("%s\n", *cpp[-2]+3);printf("%s\n", cpp[-1][-1]+1);return 0;
}

        同二,二级指针cp内存放的是将*c内元素逆转过来的,而三级指针指向的就是cp首元素,所以**++cpp就是指向的cpp向后走一个元素,即c+2,即“POINT”;*--*++cpp+3就是++cpp 指向 cp 数组的下一个元素,*--*++cpp 得到一个指向 c[0] 的指针 "ENTER",然后 +3 得到 "ER" ;*cpp[-2]+3 中 cpp[-2] 得到 cp[0],*cpp[-2] 得到 c[3],然后 +3 得到 "ST";cpp[-1][-1]+中,cpp[-1] 即*(cpp-1)得到 cp[2],cpp[-1][-1] 即 *(*(cpp-1)-1) 得到 c[1],然后 +1 得到 "EW"。答案就是POINT  ER  ST  EW

                

                C语言指针也就到此为止了,最后再次祝大家新年快乐,愿大家成为自己心目中的那个人。插一嘴哈~虽然指针结束了,但大伟的学习和博客还没有结束哦,希望大家以后继续支持大伟,加油!

衣带渐宽终不悔,为伊(知识)消得人憔悴    ------柳永

        本篇博客也就到此为止了,送大家一碗鸡汤,勉励自己以及这世界上所有追逐梦想的赤子趁年华尚好努力提升自己,莫欺少年穷!  6d1efb5acd724ec2897b21852c87ed4d.jpeg

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

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

相关文章

面试官:为什么不推荐使用 uuid 作为 mysql 主键?

我个人始终觉得&#xff0c;大多数技术是没有优劣之分的&#xff0c;在适合的地方使用&#xff0c;它就是最好的&#xff01; 面试官&#xff1a;为什么不推荐使用 uuid 作为 mysql 主键? 如果你面试遇到这个问题&#xff08;面试官并没有给出对应的场景&#xff0c;那么这家…

阿里员工:本月收入489325元,开心过年

阿里员工&#xff1a;本月收入489325元&#xff0c;开心过年 近日&#xff0c;一名阿里员工在社交媒体上爆料自己的本月收入&#xff0c;竟然高达48.9万&#xff0c;真是让人目瞪口呆。 震惊之余&#xff0c;大家都很好奇这么高收入是怎么来的&#xff0c;再仔细看工资单&…

力扣LeetCode第80题 删除有序数组中的重复项 II

一、题目 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次&#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 示…

HC-05蓝牙模块--------手机与STM32通信(代码编写)(上位机配置)保姆级教程

⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩因为之前无论是电赛还是做项目&#xff0c;都用到了蓝牙模块&#xff0c;如&#xff1a;手机和stm32的通信&#xff0c;电赛中的双车通信&#xff0c;还是遥感小车的…

X-AnyLabeling 图像标注工具及模型自动标注;json2yolo格式转换、yolo训练数据集划分

一、X-AnyLabeling 图像标注工具及模型自动标注 参考:https://github.com/CVHub520/X-AnyLabeling 1、下载 直接https://github.com/CVHub520/X-AnyLabeling/releases/tag/下载对应版本 软件打开: 2、自定义标注模型yaml构建 这里自定义模型自动标注加载预训练的yolov8…

LeetCode994腐烂的橘子(相关话题:矩阵dfs和bfs)

题目描述 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到单…

Unity坦克大战开发全流程——游戏场景——敌人——移动的敌人

游戏场景——敌人——移动的敌人 制作预制体 将坦克拖拽至场景中进行设置 写代码 让坦克在两点之间不停移动 随机坐标函数 然后在start()中调用即可 坦克要一直盯着玩家 当小于一定距离时&#xff0c;攻击玩家 重写开火逻辑 注意还要将其tag改成Monster&#xff01; 当敌人死…

虚拟化分类和实现原理

6、虚拟化分类 &#xff08;1&#xff09;完全虚拟化 直接将Hypervisor跑在0环内核态&#xff0c;客户机os跑在1环&#xff0c;一旦触发敏感指令&#xff0c;由0环的VMM进行捕获翻译&#xff0c;从而模 拟这些指令。而运行在1环的GuestOS永远都不知道自己是个虚拟机。是完全…

【Transformer】深入理解Transformer模型2——深入认识理解(上)

前言 Transformer模型出自论文&#xff1a;《Attention is All You Need》 2017年 近年来&#xff0c;在自然语言处理领域和图像处理领域&#xff0c;Transformer模型都受到了极为广泛的关注&#xff0c;很多模型中都用到了Transformer或者是Transformer模型的变体&#xff0…

OpenCV实战 -- 维生素药片的检测记数

文章目录 检测记数原图经过操作开始进行消除粘连性--形态学变换总结实现方法1. 读取图片&#xff1a;2. 形态学处理&#xff1a;3. 二值化&#xff1a;4. 提取轮廓&#xff1a;5. 轮廓筛选和计数&#xff1a; 分水岭算法&#xff1a;逐行解释在基于距离变换的分水岭算法中&…

关于链表的一些问题

求链表的中间节点 可以定义两个指针&#xff0c;一个一次走两步一个一次走一步&#xff0c;当走的快的走到NULL时&#xff0c;走的慢的就是链表的中间节点。&#xff08;此法求出的偶数个节点的链表的中间节点是它中间的第二个&#xff09; 求倒数第K个节点 也可以定义两个指…

PowerShell Instal 一键部署gitea

gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…

新手快速上手掌握基础排序<一>

目录 引言 一&#xff1a;两数互换排序 1.画图分析 2.代码实现 二&#xff1a;三数换交换排序 1.例题举例 2.代码实现 3.再比如四数互换排序&#xff0c;也可以使用两数互换的方法来实现 &#xff0c;但最好使用基础的排序方法(冒泡法&#xff0c;选择法) 三&#xf…

PointNet人工智能深度学习简明图解

PointNet 是一种深度网络架构&#xff0c;它使用点云来实现从对象分类、零件分割到场景语义解析等应用。 它于 2017 年实现&#xff0c;是第一个直接将点云作为 3D 识别任务输入的架构。 本文的想法是使用 Pytorch 实现 PointNet 的分类模型&#xff0c;并可视化其转换以了解模…

【python】爬取百度热搜排行榜Top50+可视化【附源码】【送数据分析书籍】

一、导入必要的模块&#xff1a; 这篇博客将介绍如何使用Python编写一个爬虫程序&#xff0c;从斗鱼直播网站上获取图片信息并保存到本地。我们将使用requests模块发送HTTP请求和接收响应&#xff0c;以及os模块处理文件和目录操作。 如果出现模块报错 进入控制台输入&#xff…

android开发调用百度地图api实现加载地图和定位

目录 一.踩的一些坑以及解决方法 1.权限声明不要少 2.地图初始化 3.定位问题 &#xff08;1&#xff09;监听器注册 &#xff08;2&#xff09;定位监听器类MyLocationListener的实现 &#xff08;3&#xff09;定位功能的调用 4.android studio连接真机调试问题 二.…

MySQL:索引

MySQL官方对索引的定义为: 索引 (Index) 是帮助MySQL高效获取数据的数据结构。 提取句子主干&#xff0c;就可以得到索引的本质:索引是数据结构。 1. 什么是索引&#xff0c;索引的作用 索引是一种用于快速查询和检索数据的数据结构&#xff0c;帮助mysql提高查询效率的数据…

ros2查看launch文件内需要提供的参数(接口):

格式&#xff1a;ros2 launch --show-args 包名称 launch文件名称 例如&#xff1a; ros2 launch --show-args ros_gz_sim gz_sim.python.py

行人重识别优化:Pose-Guided Feature Alignment for Occluded Person Re-Identification

文章记录了ICCV2019的一篇优化遮挡行人重识别论文的知识点&#xff1a;Pose-Guided Feature Alignment for Occluded Person Re-Identification 论文地址&#xff1a; https://yu-wu.net/pdf/ICCV2019_Occluded-reID.pdf Partial Feature Branch分支: PCB结构&#xff0c;将…

精致旅游网ROXANDREA 网页设计 html模板

一、需求分析 旅游网站通常具有多种功能&#xff0c;以下是一些常见的旅游网站功能&#xff1a; 酒店预订&#xff1a;旅游网站可以提供酒店预订服务&#xff0c;让用户搜索并预订符合其需求和预算的酒店房间。 机票预订&#xff1a;用户可以通过旅游网站搜索、比较和预订机票…