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

news2024/9/22 19:35:36

❤博主CSDN:啊苏要学习

  ▶专栏分类:C语言◀

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

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

目录

前言:

一.字符指针

二.指针数组

三.数组指针

四.数组、指针参数

4.1一维数组传参

​编辑4.2二维数组传参 

​编辑4.3一级指针传参 

4.4二级指针传参

五.函数指针

六.类型重定义


前言:

  “爷爷,爷爷!你关注的啊苏博主终于更新啦!”,博主六月中旬在忙期末复习,七月在搞军训,兜兜转转,落下了两个月。

  现在要快马加鞭学习总结知识啦!今天总结的知识是指针进阶,干货满满,希望大家喜欢。

一.字符指针

  在指针初阶的文章里面,我们已经初步认识指针是存放地址的变量,然后通过解引用操作,可以找到对应空间里的值。

  字符指针是存放字符变量地址的变量,比如:

  我们知道对字符数组有两种初始化方式,请看:

  arr1数组名本质是首字符'h'的地址,那么同为字符数组的arr2,也应该表示首元素的地址,这样得出一个结论:

  字符串"helloworld"实际上表示'h'的地址;

   既然字符串是字符的地址,那就可以用字符指针管理字符串:


  讲到这里,大家对字符指针有更进一步的认识了,接下来补充一个点:

  改变数组的首字符'h'是没问题的,改变字符指针的就出问题了,原因是:

  数组通过字符串的形式初始化,数组里的内容可以改,而字符指针管理的字符串,是一个常量字符串,不能被修改。 

二.指针数组

  指针数组,存放指针的数组。我们使用指针数组来模拟实现一下二维数组:

int main()
{
    int arr1[] = {1,2,3,4,5};
    int arr2[] = {6,7,8,9,10};
    int arr3[] = {11,12,13,14,15};
    //arr1、arr2、arr3是1 6 11的地址
    //整型的地址要放到整型指针中
    int* arr[] = {arr1, arr2, arr3};
    return 0;
}

  arr有三个元素,每一个元素是一个一维数组的起始地址。arr[0]是第一个元素,相当于arr1。

  假如我们要访问arr1中5个元素,我们可以直接用arr1[i],i从0—4增长;也可以像二维数组arr[0][i]这样访问。

  学习指针数组,让我们对指针和数组的关系更加清晰,这里希望读者能明白什么是指针数组,简而言之就是存放指针的数组。

三.数组指针

  数组指针是指向数组的指针,这个指针存放的是数组的地址。大家先分析两句代码分别是什么意思:

int main()
{
    int *pa[10];
    int(*pa)[10];
    return 0;
}

  第一句代码:int * pa[10]是一个指针数组,pa先和[10]结合,pa是一个数组,数组的每个元素是int*。

  第二句代码:int(*pa)[10]是一个数组指针,pa和*括起来,先成为一个指针,指向int[10]这个存放十个整型的数组。

  我们先来看一个代码:

  这种方式非常麻烦,直接用arr就可以了,根本不需要把数组的地址给数组指针,解引用找到数组,数组再解引用找到数据。

  一句话,上面是脱裤子放屁。数组指针用在二维数组里:

  总结:二维数组的数组名是一维数组的地址,解引用一层,得到一维数组的数组名,是数据的地址,再解引用一层,得到数据。

四.数组、指针参数

  在使用库函数或者是自定义函数时,常常需要传递实参,形参要接收。

  不论是给了实参写形参,还是根据形参写实参,都需要遵循类型匹配的原则,这样才不会出错。

4.1一维数组传参

4.2二维数组传参 

4.3一级指针传参 

4.4二级指针传参

五.函数指针

  函数在调用的时候,也会开辟栈空间,相应的也会有地址,那么存放函数地址的指针就叫做函数指针。

  不难看出,pf是一个指向Add函数的指针,解引用的*实际上是摆设,可以不加,但是如果加上,一定要括号括起来(*pf)。

  否则,执行的逻辑就是,pf(3,5)调用返回8这个值,然后对8解引用,这是错误的。

  接下来看看这两个代码分别表示什么意思:

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

  这句代码是什么意思呢?咋一看,跟没看差不多,完全不知所语,博主一开始也是一样~

  0本来是一个整型,使用C语言中的强制类型转换,把0转换为一个函数的地址,这个函数没有参数、没有返回值。

  然后使用解引用的方式调用这个函数,所以这句代码的本质是一次调用以0为地址处的函数

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

  这句代码的本质是一句函数声明,我们来分析一下:

  signal先和括号结合,说明是一个函数,参数是int,和以int为参数,返回类型为空的函数指针;
  去掉函数名和参数部分,剩下的就是函数的返回类型,也是一个函数指针。

  相信读者已经懂为什么这是一个函数声明的原因了,我们想了想,这种代码可读性那么差,真实不方便!于是:

六.类型重定义

  在初始C语言中,typdef能将类型重新定义,以至于不会让代码看起来冗长,难以理解,函数指针也是类型,也可以重定义。

int main()
{
    typdef unsigned int u_int;
    typdef int*  ptr_t;

    //数组指针类型这样重定义可行吗?
    typdef int(*)[10] parr_t;
    typdef int(*)(int, int) pf_t;

    //更改
    typdef int(*parr_t)[10];
    typdef int(*pf_t)(int, int);
    return 0;
}

  前面我们创建一个数组指针和函数指针的书写的时候,先是(),里面放*和一个变量名确保变量是一个指针。

  在类型重定义的时候也是一样,要把重新定义的名字放在(*)里面,更改后的写法才是正确的。这样再对前面第二段代码进行简化。

int main()
{
    //重定义参数为int,返回类型为空的函数指针类型
    typdef void(*pf_t)(int);

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

    //简化
    pf_t signal(int, pf_t);

    return 0;
}

  简化后是多么令人心情愉悦啊。

  好的,这篇文章内容也差不多了,还有一部分的讲解我们留给下一篇,如果你喜欢,可以留个大拇指噢~

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

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

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

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

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

相关文章

html富文本编辑器

接了个单子&#xff0c;需要添加一个文章模块&#xff0c;一看用到的技术这么老&#xff0c;人傻了&#xff0c;纯html css js 。 在普通页面中 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"…

word xls有用小技巧

不少office、代码编辑等软件&#xff0c;很简单高效小技巧。Word xlsx 某一行或列不动&#xff1a; 视图》冻结窗格》冻结首行 eclispe 全局搜索 CtrlH 制定变量、名称搜索 鼠标左键点中CtrlAltG

Promethus(普罗米修斯)监控系统

一、普罗米修斯概述 Prometheus(由go语言(golang)开发)是一套开源的监控&报警&时间序列数据库的组合。适合监控docker容器。因为kubernetes(俗称k8s)的流行带动了prometheus的发展。 Overview | Prometheus 二、时间序列数据 1、什么是序列数据 时间序列数据(TimeSer…

Docker安装es以及ik分词器

1、拉取镜像 docker pull elasticsearch:7.10.12、下载对应版本的ik分词、并将它们解压到ik文件夹下&#xff0c;如图 https://github.com/medcl/elasticsearch-analysis-ik/releases 3、在服务器上创建文件夹 mkdir /usr/elklog/elk/es mkdir /usr/elklog/elk/es/data mkdi…

Android 架构模式如何选择

作者&#xff1a;vivo 互联网客户端团队-Xu Jie Android架构模式飞速演进&#xff0c;目前已经有MVC、MVP、MVVM、MVI。到底哪一个才是自己业务场景最需要的&#xff0c;不深入理解的话是无法进行选择的。这篇文章就针对这些架构模式逐一解读。重点会介绍Compose为什么要结合MV…

脑电信号处理与特征提取——6.运用机器学习技术和脑电进行大脑解码(涂毅恒)

目录 六、运用机器学习技术和脑电进行大脑解码 6.1 前言 6.2 基于脑电数据的机器学习基础分析 6.3 基于脑电数据的机器学习进阶分析 6.4 代码解读 六、运用机器学习技术和脑电进行大脑解码 6.1 前言 6.2 基于脑电数据的机器学习基础分析 6.3 基于脑电数据的机器学习进阶分…

反射简述

什么是反射反射在java中起到什么样的作用获取class对象的三种方式反射的优缺点图 什么是反射 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性&…

【yolov8+人/车流量统计】

文章目录 前言修改点PreprocessInference 总结 前言 之前写个yolov8的一个试用版&#xff0c;【深度学习】Yolov8追踪从0到1, 这要是做计数啥的,简单的一批&#xff0c;一套工程化的代码&#xff0c;给自己挖了个坑&#xff0c;说要实现一个基于yolov8的人/车流量统计. 现在要…

如何学习ARM嵌入式开发?

ARM和单片机还是有许多区别的&#xff0c;可以说比单片机的应用更为复杂吧&#xff0c;往往在单片机里只需要对一个寄存器赋值就可以的初始化&#xff0c;在ARM下就要调用库函数了。甚至每个引脚其功能都多了许多&#xff0c;相应的配置也会更为麻烦&#xff0c;但如果做多了AR…

回归分析简明教程【Regression Analysis】

为了理解回归背后的动机&#xff0c;让我们考虑以下简单的例子。 下面的散点图显示了2001年至2012年美国大学毕业生的数量。 现在根据现有的数据&#xff0c;如果有人问你2018年有多少名大学毕业生获得硕士学位呢&#xff1f; 可以看出&#xff0c;具有硕士学位的大学毕业生数量…

【数据挖掘torch】 基于LSTM电力系统负荷预测分析(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Mitmproxy的使用

目录 1.背景 2.Mitmproxy 1&#xff09;Windows安装 2&#xff09;定制开发 3&#xff09;启动 3.使用 4.问题 5.参考资料 1.背景 简单来说&#xff0c;背景就两个字“偷懒”&#xff0c;一个字“懒”。在API自动化脚本的开发中&#xff0c;一般都需要封装一下接口。如果没…

2023届浙江大学MPA提面A资格经验总结分享

本人是去年报考的浙大MPA项目&#xff0c;并通过提面获得了A资格&#xff0c;新一年浙大MPA项目提前批面试已经开始了&#xff0c;受达立易考周老师邀请来分享下我的提面经验&#xff0c;希望我的经验能对还在迷茫中的小伙伴有所帮助。 点开提面通知&#xff0c;首先看到…

2023项目管理产品排行榜:优化企业项目管理的顶级选择

随着全球竞争加剧和商业环境的变化&#xff0c;企业对项目管理的需求越来越迫切。优秀的项目管理产品能够帮助企业提高工作效率、资源利用率和项目交付质量。 本文参考了不同的产品测评网站&#xff0c;在众多项目管理产品中&#xff0c;总结了以下几款备受好评的项目管理工具&…

UNISOT让食品欺诈无处遁形

​​发表时间&#xff1a;2023年5月11日 全世界的消费者开始越来越关注食物的来源和采购方式。这是因为人们渴望吃得更健康、更用心&#xff0c;同时人们也认识到了购买可持续且合乎伦理道德的产品的必要性。 近年来&#xff0c;人们对食品溯源的渴望进一步加速&#xff0c;原…

go 中的代码漏洞检查

前言 不知道大家在开发 go 项目中有没有遇到过一些第三方包或者官方包中出现漏洞的问题&#xff0c;这些漏洞可能会影响到代码的功能、性能或者安全性。 现在针对这一问题&#xff0c;go 团队提供了 govulncheck 工具&#xff0c;帮助开发者快速地发现和修复这些漏洞。 什么…

一套AI+医疗模式的医院智慧导诊系统源码:springboot+redis+mybatis plus+mysql

一套AI医疗模式的医院智慧导诊系统源码 相关技术&#xff1a; 技术架构&#xff1a;springbootredismybatis plusmysqlRocketMQ 开发语言&#xff1a;java 开发工具&#xff1a;IDEA 前端框架&#xff1a;Uniapp 后端框架&#xff1a;springboot 数 据 库&#xff1a;mys…

利用Windows自带组件安全清理WinSXS目录的几种方法

WinSXS&#xff08;Windows Side-by-side&#xff09;是 Windows 操作系统的核心组件之一&#xff0c;位于系统目录下的一个文件夹中&#xff0c;它包含了操作系统的许多重要文件和组件&#xff0c;以及更新时对老旧软件版本的备份&#xff0c;它会随着时间的推移不断增加&…

ssh安全远程管理

目录 1、什么是ssh 2、ssh登陆 3、ssh文件传输 1、什么是ssh ssh是 Secure Shell 的缩写&#xff0c;是一个建立在应用层上的安全远程管理协议。ssh 是目前较为可靠的传输协议&#xff0c;专为远程登录会话和其他网络服务提供安全性。利用ssh 协议可以有效防止远程管理过程中…

vue3 axios接口封装

在Vue 3中&#xff0c;可以通过封装axios来实现接口的统一管理和调用。封装后的接口调用更加简洁&#xff0c;代码可维护性也更好。以下是一个简单的Vue 3中axios接口封装的示例&#xff1a; 1.首先&#xff0c;安装axios和qs&#xff08;如果需要处理复杂数据&#xff09;&am…