认识C++指针

这篇具有很好参考价值的文章主要介绍了认识C++指针。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

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

2.指针与十六进制数字

3.使用new分配内存空间

4.使用delete释放内存

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

6.使用动态数组

7.指针运算


前言:

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

  链接:《共、枚、指1》

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

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

认识C++指针

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

认识C++指针

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

2.指针与十六进制数字

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

认识C++指针

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

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

3.使用new分配内存空间

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

例子:

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

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

4.使用delete释放内存

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

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

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

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

认识C++指针

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

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

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

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

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

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

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

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

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

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

6.使用动态数组

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

认识C++指针

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

认识C++指针

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

7.指针运算

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

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

认识C++指针

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

  加油加油,再看一个就结束啦!坚持。认识C++指针

  在这里面,我们将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就是一般情况了。

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

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

  求点赞,求点赞,求点赞!你的点赞是我更新的动力^ ^。文章来源地址https://www.toymoban.com/news/detail-431227.html

到了这里,关于认识C++指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用React给XXL-JOB开发一个新皮肤(二):目录规划和路由初始化

    一. 简述 二. 目录规划 三. Vite 配置 3.1. 配置路径别名 3.2. 配置 less 四. 页面 4.1. 入口文件 4.2. 骨架文件 4.3. 普通页面 五. 路由配置 六. 预览启动 上一篇文章我们介绍了项目初始化,此篇文章我们会先介绍下当前项目的目录规划,接着对 vite 配置以便我们后续的开发,最后会根

    2024年01月20日
    浏览(44)
  • C++结构体初始化方法

    在 C++ 里可以将结构体看作没有任何成员函数的对象,下面对 C++ 结构体的几种初始化方法进行总结。 如果只是想全部初始化为 0 可以按照如下方法 结构体包含数组(数组在结构体变量定义完就初始化为0) 直接赋值的方法虽然很直观,但是如果需要初始化多个结构体变量,

    2024年02月16日
    浏览(47)
  • C++之初始化列表详细剖析

    初始化列表:以一个 冒号开始 ,接着是一个以 逗号分隔的数据成员列表 ,每个 \\\"成员变量\\\" 后面跟一个 放在括号中的初始值或表达式。 不知道大家有没有想过这样一个问题,成员函数明明可以在函数内部对成员变量进行赋值,那为什么还要搞出初始化列表这个东西呢?这个

    2024年02月06日
    浏览(55)
  • C++ | 谈谈构造函数的初始化列表

    我们知道,对于下面这个类A的成员变量 _a1 和 _a2 属于【声明】,还没有在内存中为其开辟出一块空间以供存放,真正开出空间则是在【定义】的时候,那何时定义呢?也就是使用这个类A去实例化出对象的时候 这个对象的空间被开出来了,难道里面的成员变量就一定开出空间

    2023年04月11日
    浏览(96)
  • 【C++奇遇记】构造函数 | 初始化列表

    🎬 博客主页:博主链接 🎥 本文由 M malloc 原创,首发于 CSDN🙉 🎄 学习专栏推荐:LeetCode刷题集 数据库专栏 初阶数据结构 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📆 未来很长,值得我们全力奔赴更美好的生活✨ 🐤本篇文章将讲授C++的初始化列表相关的知识

    2024年02月12日
    浏览(55)
  • C++中包含初始化列表的构造函数

    构造函数对初始化成员变化很有用。另一种初始化成员的方式是使用初始化列表。对于程序中接受两个参数的构造函数,其包含初始化列表的变种类似于下面这样: 格式为: :成员变量1(参数1),成员变量2(参数2) 编译器会将初始化列表一一转换成代码,并将这些代码放

    2024年02月05日
    浏览(53)
  • C++二维数组的初始化赋值及示例

    C++二维数组可以看作一个表格,横向为表格的行,纵向为表格的列,数组定义时行号在前,列号在后。二维数组的定义格式为: 数据类型  数组名[常量行表达式][常量列表达式] 。 二维数组的元素是按先行后列的顺序存放的,例如,定义一个int a[3][2]的数组,其形式为: a[

    2024年02月12日
    浏览(55)
  • c++初始化vector的几种方法

    在C++中,vector是一种动态数组,可以在运行时自由添加、删除元素。初始化vector是创建一个vector对象并为其分配内存空间的过程。以下是C++中初始化vector的几种方法: 默认构造函数 使用默认构造函数创建一个空的vector,如下所示: std::vectorint vec; // 创建空vector 这种方式可用

    2024年02月16日
    浏览(40)
  • C++笔记之初始化二维矩阵的方法

    —— 2023年5月20日 上海 code review!

    2024年02月04日
    浏览(53)
  • C++:初始化列表,static成员,友元,内部类

    个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C++》 本篇博客作为C++:初始化列表,static成员,友元,内部类的知识总结。 初始化列表:以冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。 初始化

    2024年02月07日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包