当前位置: 首页 > news >正文

【C语言】如何理解多级指针?

哈喽,大家好,今天这篇文章主要是带你去看一下我们在学习指针的时候的重难点,也是我们经常蒙蔽的地方,那就是指针之中的多级指针。

 再看这篇文章的时候,相信你已经对指针有了一个基础的了解,那么我们的多级指针,它就是指针的指针的指针,我们在理解这个知识的时候一定要去抽丝剥茧的逐层分析,那么我们先来看一下二级指针吧。

定义一个二级指针

int **q;

我们可以将int**q 分为两部分来看,即为 int* 和 (*q),对于后面 (*q) 中的“*”表示 q 是一个指针变量,而前面的 int* 表示指针变量 q 只能存放 int* 型变量的地址。所有对于二级指针甚至多级指针,我们都可以把它拆成两部分。首先不管是多少级的指针变量,它都是一个指针变量,指针变量就是一个“*”,其余的“*”表示的是这个指针变量只能存放什么类型变量的地址。

 首先这里我们定义了一个指针p,相信大家了解过指针的都可以看明白;

 那下面我们就来晋级到这一页,看在这里我们q存放的是p的地址,所以呢,我们的*q就是指向的p,那我们p是一个指针,也就是*p指向的是111这个数字,那对于q而言呢,我们就要**q才能去指向其第一个值,这也就是我们的二级指针了。

相信大家这个例子并不难理解吧!

那下面我们定义一个三级指针:

int ***p = &q ;

在这里我们要先去了解一下 & 符号,在这里我们使用的这个符号并不是按位与符号,这里我们使用的是返回变量的地址符号,也就是&a,会返回a变量的指定地址即可,对于这节的要求,我们只需要掌握那么多就可以了。

 这时我们来看一下这场图,指针还是和二级类似,r存放的是q的地址,所以*r就是指向q,而q里面存放的是p的地址,所以**r就是指向了p里面的变量,而p里面存放的是111的地址,所以我们***r就是指向的111,这时我们输出***r也就是111了。

再来看 & 符号,在这里r里面存放的是q的地址,所以对q取地址也就是r内部的变量了,所以&q=r; 同理我们看p,q存放的是p变量地址,所以呢,我们对p取地址也就是q内部变量了,所以&p=q;继续来看,我们以及知道了&p是p元素地址也是我们q所指向的变量,那么&&p = &q了嘛,所以&&p也就是r内部存放的变量,也就是q的地址了。

在看完上面图解的内容后,我们再去尝试拆分查看代码。

在这里我们按照上面的方法去进行逐步拆分,  p的基类型就是 int** 型。而 q 的基类型是 int* 型,所以 &q 的基类型是 int** 型。所以 r 有三个“*”才能指向 q 的地址。三个“*”表示三级指针,即指针的指针的指针。三级指针需要三个“*”才能指向最终的内存单元。

	int a = 10 ;
	int *p = &a ; //一级指针
	*p = 100 ; //*p就是a

	int **q = &p ;
	//*q就是p
	//**q就是a

	int ***t = &q;
	//*t就是q
	//**t就是p
	//***t就是a

看上面这串代码,指针变量的“基类型”用来指定该指针变量可以指向的变量的类型,即该指针变量只能存放什么类型变量的地址。所以 int*p 表示 p 指向的是 int 型变量,也就是说里面只能放int类型的变量地址。这时的p表示a的地址,而*p等于a ;

好的现在我们向下继续看,到了二级指针这里,在这里为什么我们在存放&p的时候要使用两个**呢?前面我们知道,*p是我们的int类型,p是表示的a的地址,我们在存放p时使用int*类型去存放,那么当我们存放&p的时候,就要使用int**去存放了。

那下面我们同理,由上面可知,存p应该使用int*类型,存&p应该使用int**类型,同时q也等价于&p,那么存q就要使用int**类型,所以题目中存&q就理所当然的要使用int***类型啦。那么我们反过来看,t存的是&q,那么*t就是q了;而**t也就是*q也就p了;***t也是*p也是我们一开始设定的变量a了。

所以对于多级指针我们一定要将p或者q等当作一个变量,将int*****等当作一个一个类型来看就可以了。

这也就是我们的多级指针了,也是我们在学习C语言时最大的拦路虎之一了,加油,相信你可以的! 

相关文章:

  • 【golang】sorter 的两种实现方式
  • 2022.9.2 OpenCV课程群思考题
  • 408王道操作系统强化——文件管理及大题解构
  • 【MyBatis笔记10】Mybatis中几个动态SQL标签和内置参数
  • 7.Nodejs新特性async和await的使用
  • 怎么安装一个简单的vue3.0框架。整个流程.::
  • 【延展Extension Objective-C语言】
  • IDA* AcWing 181. 回转游戏
  • Web3小知识集锦
  • tensorflow基础
  • android自定义Apk名称和指定生成的路径
  • java框架----SSM快速整合教程
  • mongodb基本操作及使用
  • jQuery中的函数
  • leetcode:188. 买卖股票的最佳时机IV
  • 【剑指offer】让抽象问题具体化
  • canvas绘制圆角头像
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • Facebook AccountKit 接入的坑点
  • js学习笔记
  • js中的正则表达式入门
  • JS字符串转数字方法总结
  • Linux下的乱码问题
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • orm2 中文文档 3.1 模型属性
  • python 装饰器(一)
  • Windows Containers 大冒险: 容器网络
  • 动态规划入门(以爬楼梯为例)
  • 聊聊directory traversal attack
  • 使用 QuickBI 搭建酷炫可视化分析
  • 说说动画卡顿的解决方案
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #ifdef 的技巧用法
  • #Java第九次作业--输入输出流和文件操作
  • #Z2294. 打印树的直径
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (三分钟)速览传统边缘检测算子
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (一)kafka实战——kafka源码编译启动
  • (转)母版页和相对路径
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • *** 2003
  • **PHP分步表单提交思路(分页表单提交)
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .net core Swagger 过滤部分Api
  • .Net mvc总结
  • /dev/sda2 is mounted; will not make a filesystem here!
  • @Autowired 与@Resource的区别
  • @TableLogic注解说明,以及对增删改查的影响
  • [ 数据结构 - C++] AVL树原理及实现