C++编程基础|多级指针

news2024/10/2 22:29:30

C++编程基础|多级指针

  • 一级指针
  • 二级指针
  • 三级指针
  • 多级指针的意义
    • 一维数组与数组指针
    • 二维数组与数组指针

在看代码时发现下面的内容

GridNodePtr *** GridNodeMap;
struct GridNode;
typedef GridNode* GridNodePtr;

显而GridNodePtr是结构体GridNode首地址指针

那么GridNodeMap是什么?它实际上是一个四级指针

这种用法不多,这里的含义之后再给出

下面分别梳理下:

  • 一级指针
  • 二级指针
  • 三级指针

一级指针

一级指针其实就是我们平时常见的普通指针

int a = 15;      
int * b = &a;    //一级指针,定义一个指针变量b,将整型变量a的地址(指针)赋值给b

一级指针,定义一个指针变量b,将整型变量a的地址(指针)赋值给b
在这里插入图片描述
指针其实是一个内存地址,对于一个内存单元来说,单元的地址即为指针。

平时常用的指针则是指针变量
指针变量从字面意思上可以看出是存储指针的一种变量类型。在C语言中,允许用一个变量来存放指针,这种变量称为指针变量
也就是,指针是一个地址,是一个常量。而指针变量却可以赋予不同的指针(指针也就是地址),是变量。但我们常把指针变量简称为指针。

指针其实就是地址的别称,而指针变量就是存放这个地址的,所以我们平时说的定义一个指针,就是定义一个指针变量,我们可以给这个指针变量赋上变量的地址、数组首地址、结构体首地址等等

另外注意一下指针变量的赋值只能赋予地址

&:取地址运算符,一般形式为: &变量名
*:指针运算符(也就是获取该指针所指向的数据),一般形式为: *指针变量

二级指针

二级指针则是指向一级指针的指针,也就是说如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。

int a = 15;     
int * b = &a;    //一级指针
int **c = &b;    //二级指针,指针c指向的是指针b,也就是说二级指针c存储的是一级指针b的地址

二级指针,指针c指向的是指针b,也就是说二级指针c存储的是一级指针b的地址

在这里插入图片描述
指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址,所以二级指针才可以指向一级指针的地址。

三级指针

三级指针则是指向二级指针的指针。所以规律就是n 级指针就是 指向 n-1 级指针的 指针

int a = 15;     
int * b = &a;    //一级指针
int **c = &b;    //二级指针,指针c指向的是指针b,也就是说二级指针c存储的是一级指针b的地址。
int ***d = &c;   //三级指针,指针d指向的是指针c的地址

在这里插入图片描述

三级指针前面加一个取地址运算符,也就是&d,则取出的是其自身的存储地址。

而”*d”则是取到指针c的地址,而”**d”则是取到指针b的地址,而”***d”则是取到a地址上的数据。

想要获取指针指向的数据时,一级指针加一个*,二级指针加两个*,三级指针加三个*

int **a = new int *[2]; //一维 

for (int i=0; i<2; i++) 
	{ 
		(*a+i) = new int[i+1]; //二维变长 
	}

多级指针的意义

这样的指来指去目的是啥呢?有什么意义呢?

其中有些是如果遇到需要修改指针的值,使它指向另外一个节点,或变量,与其使用大量代码直接修改它的值,不如使用它的二级指针,直接修改其地址值,会大大减少代码冗余,提高代码质量。

但是最开始的例子是为了用多级指针去表示多维数组

一维数组与数组指针

假如有一维数组如下:

char a[3];

该数组一共有3个元素,元素的类型为char

一个数组的数组名代表其首元素的首地址也就是相当于&a[0],而a[0]的类型为char
&a[0]类型为char *

可以定义如下的指针变量,指向该数组

char* p = a;//相当于char * p = &a[0]

在这里插入图片描述

a和&a[0]代表的都是数组首元素的首地址

&a的值打印出来,会发现该值也等于数组首元素的首地址

&a虽然在数值上也等于数组首元素首地址的值,但是其类型并不是数组首元素首地址类型
对数组名进行取地址操作,其类型为整个数组

很多人对类似于a+1,&a+1,&a[0]+1,sizeof(a),sizeof(&a)等感到迷惑,其实只要搞清楚指针的类型就可以迎刃而解。比如在面对a+1和&a+1的区别时,由于a表示数组首元素首地址,其类型为char*,因此a+1相当于数组首地址值+sizeof(char);而&a的类型为char (*)[3],代表整个数组,因此&a+1相当于数组首地址值+sizeof(a)。(sizeof(a)代表整个数组大小,前文第7条说明,但是无论数组大小如何,sizeof(&a)永远等于一个指针变量占用空间的大小,具体与系统平台有关)

二维数组与数组指针

假如有如下二维数组:

char a[3][2];

实际上并不存在多维数组,
可以将a[3][2]看成是一个具有3个元素的一维数组,只是这三个元素分别又是一个一维数组

实际上,在内存中,该数组的确是按照一维数组的形式存储的,存储顺序为(低地址在前):a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]

在这里插入图片描述
如上图所示,我们可以将数组分成两个维度来看,首先是第一维,将a[3][2]看成一个具有三个元素的一维数组,元素分别为:a[0]、a[1]、a[2],其中,a[0]、a[1]、a[2]又分别是一个具有两个元素的一维数组(元素类型为char)。从第二个维度看,此处可以将a[0]、a[1]、a[2]看成自己代表”第二维”数组的数组名,以a[0]为例,a0代表的一维数组是一个具有两个char类型元素的数组,而a[0]是这个数组的数组名(代表数组首元素首地址),因此a[0]类型为char * ,同理a[1]和a[2]类型都是char * 。而a是第一维数组的数组名,代表首元素首地址,而首元素是一个具有两个char类型元素的一维数组,因此a就是一个指向具有两个char类型元素数组的数组指针,也就是char(*)[2]。

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

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

相关文章

centos离线安装telnet、traceroute工具

安装包下载地址 安装包下载地址在这里 直接输入包名&#xff0c;筛选系统&#xff0c;根据自己系统版本确定该下哪个包 centos离线安装telnet 准备三个安装包 xinetd-2.3.15-14.el7.x86_64.rpmtelnet-server-0.17-65.el7_8.x86_64.rpmtelnet-0.17-65.el7_8.x86_64.rpm 三个…

线性代数中涉及到的matlab命令-第二章:矩阵及其运算

目录 1&#xff0c;矩阵定义 2&#xff0c;矩阵的运算 3&#xff0c;方阵的行列式和伴随矩阵 4&#xff0c;矩阵的逆 5&#xff0c;克莱默法则 6&#xff0c;矩阵分块 1&#xff0c;矩阵定义 矩阵与行列式的区别&#xff1a; &#xff08;1&#xff09;形式上行列式…

贴片电容材质的区别与电容的主要作用

一、贴片电容材质NPO、COG、X7R、X5R、Y5V、Z5U区别 主要是介质材料不同&#xff0c;不同介质种类由于它的主要极化类型不一样&#xff0c;其对电场变化的响应速度和极化率也不一样。在相同的体积下的容量就不同&#xff0c;随之带来的电容器介质的损耗、容量的稳定性也就不同…

Vue2知识总结

vue2复习回顾 vue基础 想让vue工作&#xff0c;就必须创建一个vue实例&#xff0c;并且传入一个配置对象 【el data 】 <!-- 准备好一个容器 --><div id"demo"><h1>Hello&#xff0c;{{name.toUpperCase()}}&#xff0c;{{address}}</h1>…

天猫商品品牌数据采集接口,天猫商品详情数据接口,天猫API接口

天猫商品品牌数据采集方法如下&#xff1a; 打开天猫&#xff0c;进入任意一个品牌的商品页面。点击浏览器右上角的“选项”按钮&#xff0c;选择“检查元素”或使用快捷键CtrlShiftI&#xff08;Windows&#xff09;或CmdOptionI&#xff08;Mac&#xff09;打开开发者工具。…

Spring是什么?为什么要使用Spring?

目录 前言 一、Spring是什么&#xff1f; 1.1 轻量级 1.2 JavaEE的解决方案 二、为什么要使用Spring 2.1 传统方式完成业务逻辑 2.2 使用Spring模式完成业务逻辑 三、为什么使用Spring&#xff1f; 前言 本文主要介绍Spring是什么&#xff0c;并且解释为何要去使用Spring&…

【Python 零基础入门】 Numpy

【Python 零基础入门】第六课 Numpy 概述什么是 Numpy?Numpy 与 Python 数组的区别并发 vs 并行单线程 vs 多线程GILNumpy 在数据科学中的重要性 Numpy 安装Anaconda导包 ndarraynp.array 创建数组属性np.zeros 创建np.ones 创建 数组的切片和索引基本索引切片操作数组运算 常…

TypeScript React(上)

目录 扩展学习资料 TypeScript设计原则 TypeScript基础 语法基础 变量声明 JavaScript声明变量 TypeScript声明变量 示例 接口 (标准类型-Interface) 类型别名-Type 接口 VS 类型别名 类型断言:欺骗TS&#xff0c;肯定数据符合结构 泛型、<大写字母> 扩展学习…

Vulnhub系列靶机---Raven2

文章目录 Raven2 渗透测试信息收集提权UDF脚本MySQL提权SUID提权 Raven2 渗透测试 信息收集 查看存活主机 arp-scan -l 找到目标主机。 扫描目标主机上的端口、状态、服务类型、版本信息 nmap -A 192.168.160.47目标开放了 22、80、111 端口 访问一下80端口&#xff0c;并…

VSCode 快速移动光标至行尾

最近在用vscode进行C编程&#xff0c;经常需要把光标跳到行尾去添加符号。 手动到行尾太麻烦了。 一种快捷方式是&#xff1a;用键盘上的“END”快捷键。 但是用这个键也不是很方便&#xff0c;因为“end”键离主键盘区太远。 另一种便捷的方式是&#xff1a;给vscode设置自定义…

分权分域有啥内容?

目前的系统有什么问题&#xff1f; 现在我们的系统越来越庞大&#xff0c;可是每一个人进来的查看到的内容完全一样&#xff0c;没有办法灵活的根据不同用户展示不同的数据 例如我们有一个系统&#xff0c;期望不同权限的用户可以看到不同类型的页面&#xff0c;同一个页面不…

计算机毕业设计选什么题目好?springboot 高校就业管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

供应链 | 零售商-供应商柔性承诺契约:一种鲁棒优化方法 (一)

论文解读&#xff1a;毕鑫宇 作者&#xff1a;Aharon Ben-Tal, Boaz Golany, Arkadi Nemirovski, Jean-Philippe Vial 引用&#xff1a;Ben-Tal, A., Golany, B. , Nemirovski, A., & Vial, J. P… (2005). Retailer-supplier flexible commitments contracts: a robust op…

内存空间的分配与回收之连续分配管理方式

1.连续分配管理方式 连续分配:指为用户进程分配的必须是一个连续的内存空间。 1.单一连续分配 在单一连续分配方式中&#xff0c;内存被分为系统区和用户区。系统区通常位于内存的低地址部分&#xff0c;用于存放操作系统相关数据;用户区用于存放用户进程相关数据。内存中只…

十六、 代码校验(3)

本章概要 测试驱动开发 测试驱动 vs 测试优先 日志 日志信息日志等级 测试驱动开发 之所以可以有测试驱动开发&#xff08;TDD&#xff09;这种开发方式&#xff0c;是因为如果你在设计和编写代码时考虑到了测试&#xff0c;那么你不仅可以写出可测试性更好的代码&#xff…

计算机导论实验——Linux基础入门

使用Xshell登录 Linux 主机 linux命令&#xff1a; cd&#xff1a;去哪里 pwd&#xff1a;在哪里 ls&#xff1a;查看当前有什么文件 mkdir&#xff1a;创建新目录 cp&#xff1a;复制 cat&#xff1a;连接或显示文件 rm&#xff1a;删除 mv&#xff1a;用于移动或重命名文件…

B站视频“多模态大模型,科大讯飞前NLP专家串讲”记录

文章目录 多模态&#xff1a;对齐 -- align迁移学习和zero-shotClipBlip 多模态&#xff1a; 图片、文字、视频、语音等不同的表征。 表示信息的方式有多种&#xff0c;但是不同的表示方式携带的信息不完全相同。 对齐 – align 如第一个图中&#xff0c;文字内容的描述和图…

关于一篇什么是JWT的原理与实际应用

目录 一.介绍 1.1.什么是JWT 二.结构 三.Jwt的工具类的使用 3.1. 依赖 3.2.工具类 3.3.过滤器 3.4.控制器 3.5.配置 3.6. 测试类 用于生成JWT 解析Jwt 复制jwt&#xff0c;并延时30分钟 测试JWT的有效时间 测试过期JWT的解析 四.应用 今天就到这了&#xff0c;希…

基于SpringBoot的网上订餐系统

基于SpringBoot的网上订餐系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;用户、管理员管理员&#xff1a;登录、个人中心、会员管理、…

【Unity】【VR】详解Oculus Integration输入

【背景】 以下内容适用于Oculus Integration开发VR场景,也就是OVR打头的Scripts,不适用于OpenXR开发场景,也就是XR打头Scripts。 【详解】 OVR的Input相对比较容易获取。重点在于区分不同动作机制的细节效果。 OVR Input的按键存在Button和RawButton两个系列 RawButton…