认识C++指针

news2025/1/23 13:37:10

目录

前言:

1.指针未初始化的危险性

2.指针与十六进制数字

3.使用new分配内存空间

4.使用delete释放内存

5.使用new来创建动态数组 

6.使用动态数组

7.指针运算


前言:

  期待已久的指针篇来啦,这篇全都是有关指针的知识,喜欢指针的读者可以大饱眼福^ ^关于指针的声明和初始化等部分,我在共用、结构里讲过了,需要的读者可以点进去看一下再返回来。

  链接:《共、枚、指1》

1.指针未初始化的危险性

  我们知道指针是存放地址的变量。当我们创建了一个指针的时候,但并没有初始化,在后面我们还对这个未初始化的指针解引用了,就会对内存产生破坏,导致程序挂掉

   创建指针变量的时候,计算机不会为指针指向的内存单元编号开辟空间。

  当我们用p指针里的地址去找到相应的内存空间并对它进行操作,可不敢这样做,那样是犯法的故事性理解:就好像你知道了一个旅馆的一个房间地址,但你知道并不代表你拥有这个房间,你来到这个旅馆,没跟馆主说,你径直的冲到这个房间门口,强行打开房间门,里面有小明躺在床上睡觉,你一脚把它踹开,自己躺在床上睡觉,还赖皮的不走了,馆主表示无奈,并报了警

2.指针与十六进制数字

  我们知道,地址是用十六进制表示的,但数字的十六进制和地址的十六进制的意思是截然不同的,虽然计算机通常把地址当做整数来处理。但我们知道数字是描述数值的,指针描述的是位置

  计算机把地址当做整数来处理的意思是:指针变量存储的值(也就是地址),就是在按照存储整型的方式存到内存中的,取出来的时候也是按整型取的

  但我们要记得的是:十六进制数值,和十六进制地址不是一回事就OK。

3.使用new分配内存空间

  ​使用new运算符在运行阶段开辟堆区空间,开辟的空间大小根据我们给new后面加的数据类型,而且我们需要使用同类型的指针来接收new返回来的地址

例子:

  指针的大小是固定不变的,不管指针指向什么类型的地址,指针的大小只与平台位数有关。是32位平台就是4字节64位平台就是8字节

  这里面pn、pd是用来接收new开辟出来的内存空间的地址,这块内存空间没有名称,只能用指针去访问而普通变量,内存空间有名称。比如int a = 10;&a是a变量的内存地址,用a这个名称来标记这块空间,就可以直接用a来访问里面的值

4.使用delete释放内存

  在用new申请内存的时候,当我们不需要用了的时候,必须将这块申请的内存交还给操作系统,否则内存将会越来越少,直到没有多余的内存空间让程序运行起来。

  在C++中,我们使用delete来释放使用new开辟的空间,格式是:delete 指针;(接收new开辟空间返回地址的那个指针),本质上是释放掉new开辟的空间,因为这个接收的指针就是new开辟的地址,所以这么写也是没问题的。

  特别注意的是new和delete是要配套使用的。 

delete使用注意事项
delete只能用来释放用new开辟的空间
不能对同一块new开辟的空间释放两次
对空指针使用delete是没事的,相当于delete什么都没做

  我们这里是用delete释放pd,pd指向的那块地址也是new开辟的,因为ps将值赋给了pd,其实delete释放ps也可以,但不要都释放,不然就对同一块new空间释放两次了。

5.使用new来创建动态数组 

  静态联编:通过声明创建数组,则在程序被编译时将为它分配内存空间,不管程序最终使不使用数组,它都存在,并占用空间。在编译时给数组分配内存被称为静态离联编

  而在运行阶段需要数组,则创建数组,不需要就不创建。还能在程序运行时确定数组的长度这被称为动态联编。这种数组叫做动态数组。  

  使用静态联编,必须在编写程序时指定数组的长度。使用动态联编时,程序可以在运行时确定数组的长度

   当我们使用new时带上方括号以及数目的时候,也就是在跟new传达开辟数组空间的信号,相应的释放掉数组空间也要给delete加上方括号用new没有用方括号,delete也不用带

  补充:对于ANSIC和ISO标准来说,new和delete的格式不匹配的结果是未知的。

总之就是:使用new来创建动态数组的时候,要用对应的格式和new匹配起来,需要补充的一点是这种情况new int[1];,new[]只为一个实体分配内存,用不带[]的delete来释放。看下面代码:

  pd是指向一个double(数组第一个元素)的指针,我们需要负责把数组的元素确定好,因为编译器不能对pd是指向10个double元素中的第一个进行确定。什么意思呢?也就是说当我们忽略数组的元素个数的时候,编译器不知道你这个首元素地址是10个元素大的数组的首元素地址,还是20个元素大的数组的首元素地址,所以不能省略数组元素的个数。

  知道动态数组怎么创建和怎么释放后,我们来讨论如何使用动态数组

6.使用动态数组

  数组表示法将指针当做数组名使用即可

  数组名是一般情况下是首元素地址,数组名的值是不能变的而指针是变量,可以通过加减来改变所指向的地址。例如parr = parr + 1;,使得parr原本指向第一个元素变成了指向第二个元素。

  parr[0]就是第一个元素。parr[0]是第二个元素是因为parr+1了,指向了第二个元素。把指针当做数组名来使用,并不是就不能用指针的方式来访问数组了,我们知道parr是数组第一个元素的地址,用解引用可以访问到该地址的值,所以*parr和parr[0]是等价的。我们来讲完指针的运算,就会更清晰了。

7.指针运算

  在C和C++中数组和指针基本是等价的等价的原因不只是因为C和C++内部都使用指针来处理数组,也在于指针算术

  将一个整数加1,其值将增加1,但指针增加1,它的值增加的大小取决于指针的类型。

  i的值增加1,这我们都理解。指针的值从E8变到EC(十六进制 C是12),增加了4,恰好是一个整型的大小,所以指针的加减运算是让指针变量跳过n个指针类型,值也相应加减n个指针类型的大小。例子:double df = 3.14;double* pd = &df;pd+1;pd的值将增加8。

  加油加油,再看一个就结束啦!坚持。

  在这里面,我们将wages(数组名)给double类型的指针初始化,可行的原因正是因为数组名是首元素的地址,数组的元素是double类型的,double类型的地址给double指针初始化那再合理不过了

  pd在加1前,打印的值是A8,加一后是B0,增加了8。因为pd跳过了一个double类型(占8个字节)。有些读者可能就要问了,为什么让值增加8呢?其实是因为,每个地址编号对应的内存单元占一个字节第一个元素占8个字节也就是8个编号,而指针指向头个内存单元。A8是第一个元素的头个字节,还有A9,AA一直到AF,算上A8是8个字节。然后指针加一指向下一个元素,而数组又是连续存储元素的,紧接着指针就指向了B0,这就是为什么会加8的原因

  来到20、21行,这里就是指针访问和数组表示的关系。我们已经知道数组是首元素地址了,stacks[0]就相当于*(stacks+0),stacks加0还是首地址,解引用就是首个元素

  也就是假设:在这里我们用指针ps来接收stacks,就可以用这些操作,*ps就是首元素,*(ps+1)是指针指向首元素的下一个元素后解引用得到第二个元素,ps[0]是*(ps+0),ps[1]是*(ps+1)。

  数组名的意思:在最后sizeof(wages),wages不是数组首元素地址的意思,而是整个数组的意思。wages每个元素8字节,数组有三个元素,就是24字节

数组名
&arr整个数组的地址
arr数组首元素地址
sizeof(arr)整个数组的大小

  一般情况下数组名都是首元素地址,有且仅有两种情况是值整个数组,单纯&arr和单纯sizeof(arr),加单纯的意思就是说只能是这种形式下的数组名才指整个数组。sizeof(arr+1),这里的arr就是一般情况了。

  到这里指针的大部分基本知识就讲完啦,还有指针与字符串、指针与类型的组合等,我们下节再讲。最重要的是对使用要熟练使用指针解决问题

  希望读者读完有所收获,如果本篇博客有内容上的错误或排版、内容分布不合理,请评论跟博主讲!

  求点赞,求点赞,求点赞!你的点赞是我更新的动力^ ^。

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

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

相关文章

【Matlab算法】粒子群算法求解二维线性优化问题(附MATLAB代码)

MATLAB求解二维线性优化问题前言正文函数实现可视化结果前言 二维线性优化问题指的是在二维空间中,对于一个由线性函数构成的目标函数,通过限制自变量的范围或满足特定的约束条件,寻找一个最优解(最小值或最大值)。这…

【精华】表格结构识别模型研究进展

表格结构识别模型研究进展 合合信息:表格识别与内容提炼技术理解及研发趋势 OCR之表格结构识别综述 表格识别技术综述 用于表检测和结构识别的深度学习:综述 (1)PP-Structure 速度提升11倍,一键PDF转Word PP-St…

MATLAB | 这些各种各样的花里胡哨的折线填充图咋画

这些各种各样的花里胡哨的折线填充图咋画? 折线下面填充纯色的话area函数很容易做到,但上面那些各种花里胡哨的填充图就没那么容易做到了,本期就来讲讲这些玩意都是咋画的: 事先说明,为了绘图好看本文绝大多数图像都使…

Vue3步骤条(Steps)

Vue2步骤条&#xff08;Steps&#xff09; 可自定义设置以下属性&#xff1a; 步骤数组&#xff08;steps&#xff09;&#xff0c;类型&#xff1a;Array<{title?: string, description?: string}>&#xff0c;默认 [] 当前选中的步骤&#xff0c;设置 v-model 后&a…

Java13-多线程

一&#xff1a;基本概念&#xff1a;程序&#xff0c;进程&#xff0c;线程 程序&#xff1a; 是完成特定任务&#xff0c;用某种语言编写的一组指令集合&#xff0c;即指一段静态的代码。 进程&#xff1a;是程序的一次执行过程&#xff0c;或是正在运行的一个程序。 线程&…

Linux系统之MobaXterm远程连接centos的GNOME桌面环境

Linux系统之MobaXterm远程连接centos的GNOME桌面环境一、MobaXterm介绍1.MobaXterm简介2.MobaXterm功能特点二、centos安装GNOME桌面1.本地环境介绍2.安装GNOME桌面环境3.本地进入Linux桌面三、MobaXterm远程连接centos1.打开MobaXterm软件2.远程连接本地Linux系统四、远程连接…

如何利用ChatGPT辅助优化刷题性能

根据土著刷题共建群里的一个小伙伴反馈&#xff0c;刷题会出现切题卡顿的情况&#xff0c;有时会出现滑不动的情况。 定位问题 为了定位切题卡顿问题的具体原因&#xff0c;测试了高低端手机&#x1f4f1;、切换2G、3G、4G低网络状态等各种影响切题的现实情况&#xff0c;经过借…

门店零售系统有哪些功能模块?能带来哪些帮助?

门店零售系统是一种用于管理门店销售、库存、采购等业务的软件系统&#xff0c;可以帮助门店提高管理效率、降低操作风险、优化运营决策&#xff0c;从而增强市场竞争力和顾客满意度。 一、门店零售系统的4大功能 1、商品管理 该模块主要用于管理门店的商品信息&#xff0c;包…

arcgis中地理配准之栅格平移

背景 前面写过一篇文章,是针对有两个对应的栅格数据进行配准的 Arcgis地理配准栅格数据 有时候需要没有对应的栅格数据,只有单幅栅格数据,而且知道平移参数,这时候可以通过平移参数来平移栅格,而且在unity中不能直接识别坐标值很大的数据,只能通过平移将坐标值减少,才…

【分布式事务AT模式 SpringCloud集成Seata框架】分布式事务框架Seata详细讲解

前言 上篇文章我们讲述了如何启动seata的本地服务&#xff0c;并且注册到nacos使用&#xff0c;这篇文章将在SpringCloud中整合Seata框架 上篇文章传送门&#xff1a;https://blog.csdn.net/Syals/article/details/130102851?spm1001.2014.3001.5501 本篇主要内容&#xff…

Docker几个概念

Docker几个概念&#xff0c;有不正确地方欢迎指正 一、首先来看一句话&#xff1a;没有Cgroups就没有LXC&#xff0c;没有LXC就没有Docker。 1、什么是Cgroup呢&#xff1f;Cgroup又名Control group&#xff0c;是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理…

VLAN 基础与划分及配置

我们都知道 VLAN 的中文名为"虚拟局域网"&#xff0c;VLAN 是一种将局域网设备从逻辑上划分成一个个不同的网段&#xff0c;从而实现虚拟工作组的新兴数据交换技术。这一新兴技术主要应用于交换机和路由器中&#xff0c;但主流应用还是在交换机之中。那今天咱们就和海…

Linux网络连接出现问题

报错截图 1.先查看NetworkManager是否启动 systemctl status NetworkManager如果输出结果中包含 "active (running)" 表示 NetworkManager 已经启动并正在运行 2.查看DNS是否配置 cat vim /etc/resolv.conf 1.查看是否有配置信息&#xff0c;如果没有请配置DNS …

华为ACL配置

模拟场景 服务器&#xff1a;192.168.3.100 销售部&#xff1a;192.168.1.1 开发部&#xff1a;192.168.2.1 模拟互联网&#xff1a;1.1.1.1 要求1&#xff1a;销售部不允许访问服务器 要求2&#xff1a;开发部可以访问服务器 要求3&#xff1a;互联网不可以访问服务器 拓扑图…

栈和队列经典题题解

目录 &#x1f349;一.括号匹配问题&#x1f349; &#x1f348;二.用队列实现栈&#x1f348; &#x1f34f;三.用栈实现队列&#x1f34f; &#x1f353;四.设计循环队列&#x1f353; &#x1f349;一.括号匹配问题&#x1f349; OJ链接力扣 题目描述&#xff1a; 思路&…

77-Linux_网络编程

网络编程一.主机字节序列和网络字节序列二.套接字地址结构1.通用socket地址结构2.专用的socket地址结构3.IP地址转换函数一.主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序&#xff0c;不同的主机采用的字节序列可能不同。 大端字节序是指一个整数的高位…

开店必备的5款超实用零售管理软件,第1个新手也能轻松使用!

现在越来越多的零售店老板都开始用零售管理软件来管理门店&#xff0c;提升效率&#xff0c;节约人力和时间成本。 但对于刚刚接触零售管理软件的老板来说&#xff0c;应用市场上的零售管理软件那么多&#xff0c;究竟哪些好用&#xff0c;哪些容易上手……还不太了解。 别着急…

CMake项目使用ctest+gtest进行单元测试

随着CMake工具越来越强大便捷&#xff0c;越来越多的C/C项目转而使用CMake来进行编译管理&#xff0c;它还提供了用于测试的ctest命令来执行项目中编写的单元测试。 本文就以一个实例来介绍如何使用ctest来进行单元测试。 一、环境准备 本文实例环境VSCodeMinGW64CMakegtest…

Qt程序CPU过高怎么定位解决?性能优化

自己开发的一个程序采用多线程调用url从网络上下载股票数据&#xff0c;一旦开启程序就特别的卡&#xff1b;想着优化一下&#xff1b;授之于鱼&#xff0c;不如 授之以渔&#xff1b; 1.CPU过高排查方法 &#xff08;1&#xff09;打开vs的性能探测器&#xff1b; &#xff…

Android端推送消息之极光推送

推送方式 轮询 --实现方式: 周期性主动获取网络中的数据; --缺点: 费电, 费流量; SMS --实现方式: 服务器端向手机端发送短信, 手机监听短信广播, 将拦截的短信信息进行显示; --优点: 省电, 省流量, 在没有网络的偏远地点也能接收到推送消息; --缺点: 费钱, 一毛钱一条;…