C++ 引用 解引用 取地址 指针 双指针 指针的引用 二级指针

2023-10-28

为了把引用 解引用 取地址 指针 双指针 指针的引用 二级指针 这一块弄清楚,钻研与查阅资料得到如下体会;

1.        引用与取地址  (reference and address)  引用的&前面一定有类型符号,否则就不是引用, 取地址的&后面一定有变量名称,一旦出现&,一定把此搞明白

 int b =10, int &a,  这明显就是引用,&b 这就是取地址, test1(int &a, int &b) 这些是引用用在定义函数的时候, test4(&a, &b) 这个时候是取地址,&后面必须是变量名字,不能是其它的,比如&*b是不容许的,

2.       引用是变量的别名,与变量有相同的地址和值, & 只在定义的时候出现,以后不用出现, int &a =b,   以后直接在使用的时候用a 代表b, 不是用&a 代表b (单独出现&a,此时就是应用的地址了, 它就是b的地址)  &a==&b,地址是相等的。函数中如传递变量,  f(b), 如需要传递变量的地址f(&b)

3.     一个变量(包括指针)包括三个部分, 变量名字, 变量的值, 变量的地址,内存中地址是唯一的, 生命周期内名字和地址是关联的,多个名字可关联一个地址,值是地址上的储存内容,可以变的,名字没有直接和值关联,名字关联地址,地址在关联值, 这三个是三回事,地址和引用,地址,解引用就是解决此三部分不同的问题。

     一般的赋值等是对变量的值赋值,而不是地址等其他的, int b=10, 是b的值赋为10, 而不是地址 int *f , f=&b, 这是把指针的值赋为b的地址,而指针f本省的地址没有涉及

4.     指针与解引用 (pointer and dereference)  指针的*前面一定有类型符号,否则就不是指针, 解引用的*后面一定要有地址(指针或相当于值是地址的变量)一旦出现×,一定高明,  int * f, 只是指针定义, 而如果单独出现 *f 这个时候是解引用,  test8(int ×a, int ×b) 这些是指针用在定义函数的时候, test9(×a, ×b) 这个时候是解引用,传递的指针对应的解引用, ×&f  这个就是变量f的地址的解引用,就是变量f的值

5 . 指针里面的值是变量的地址, × 只在定义的时候出现,以后不出现, int*f,   f=&b,  以后直接用f 代表 &b, 用*f(解引用)代表b, 代表是可以写等于的意思。而不是以后也用*f=&b, f=b.

6. 指针就是变量本身储存的值是另一个变量的地址, 和它本身的地址是两回事, 解引用是指针的值(地址)作为另一个变量的地址, 这个地址对应的值。int *f =&b, 

此时f的地址是:HHH, f的值是AAA,  b的地址是AAA, b的值是CCC,  HHH 就是&f, ×f 就是CCC。二级指针就是指向指针的指针,相当于这里的CCC又是一个变量的地址, 

7. 作为参数传递等的时候,一定要抛开类新定义时前两*或&的符号,左边的值与右边建立对等关系 ,左边值是地址,右边就是地址,左边值是值, 右边也就是普通的值,  如 fee(int* f), int k,  在实参引用的时候要fee(&h), 不能fee(h), 因为定义中*是类型符号,f的值是地址, 要与&h才一直,  fee(int &h) , int k,  在实参引用的时候要fee(k). 因为&是类型符,h是引用,值和变量一样, 而不能是地址参数fee(&h)

8.  引用不分配内存, 而指针分配, int d, int& f=d,, int *u =&d , 此时d和f 的值, 地址一模一样,u的值和d的地址上一样, u有它自己的地址。

9. 作为参数传递,指针作为参数的时候是临时拷贝一个副本( 不同的地址),它的值和原来的指针一样,及指向的地址和原来的指针指向的一样,他们有相同的解引用,因此对函数内这个临时指针的值的操作都不会影响到原来的指针,只是把临时指针的值变了,及指的地址变了,如果不对这个临时指针操作,而对它的解引用操作, 由于和原来的指针指向同一个地址,有相同的解引用,因此对临时指针的解引用操作会影响到原来的解引用,要在函数退出后而使原来的值的变化有保留,就必须把要改变的值放在传递指针的解引用里面。 要想让指针作为参数在函数中操作完后有变化有保留,因此要让产生的临时指针指向这个指针的地址,临时指针的解引用就是这个指针,临时指针的解引用变化,这个指针的值就变化,这个指针的解引用,和临时指针的解引用的解引用一致,就是二级指针或双指针。及指针用作参数传出时需要二级指针。

int *a=&b, 

int c*=&d,   

exchange(int*f, int*e),  

{

  int * temp 

temp =f;

f=e,

e=temp

}

exchange(a, c)

执行时; 

f 是一个临时指针指向b的地址, *f就是b    函数外a 指向b的地址

e是一个临时指针指向d的地址, *e就是d   函数外c指向d的地址

交换后

f 是一个临时指针指向d的地址, *f就是d    函数外a 指向b的地址

e是一个临时指针指向b的地址, *e就是b   函数外c指向d的地址

因此函数内部变了,外部没有变, 退出后还是原样子。

如果是

exchange(int*f, int*e),  

{

  int  temp 

temp =*f;

*f=*e,

*e=temp

}


exchange(a, c)


此时执行

f 是一个临时指针指向b的地址, *f就是b    函数外a 指向b的地址 *a就是b

e是一个临时指针指向d的地址, *e就是d   函数外c指向d的地址  *c就是d

交换后

f 是一个临时指针指向b的地址, *f就是d    函数外a 指向b的地址 *a就是b   但此时 b的值变成d的值了,  b的名称和地址没有变

e是一个临时指针指向d的地址, *e就是b   函数外c指向d的地址  *c就是d   但此时 d的值变成b的值了      d的名称和地址没有变

如前名称和地址是绑定的, 这次是把值变了


如果是

exchange(int**f, int**e),  

{

  int * temp 

temp =*f;

*f=*e,

*e=temp

}


exchange(&a, &c)  注意此时格式

执行时 


f 是一个临时指针指向指针a的地址, *f就是a,    * a就是b, **f就是 b,   函数外a 指向b的地址 *a就是b

e是一个临时指针指向指针c的地址, *e就是c    *c就是d, **e就是 d     函数外c指向d的地址  *c就是d

执行后

f 是一个临时指针指向指针a的地址, *f就是a, 此时a的名称和地址没有变,但值变成了c的值   * a就指向* c 即 d, **f就是 d,   函数外a 指向d的地址 *a就是d

e是一个临时指针指向指针c的地址, *e就是c  此时c的名称和地址没有变, 但值变成a的值,  *c就指向*a  即 b, **e就是 b     函数外c指向d的地址  *c就是b

这样的操作是在指针的值的层面上做了交换,上面一种是在原数据基础上做了交换。 

10. 引用作为参数,是直接把实参的地址和值当作引用的,起了个别名,相当于给这段地址关联了一个名字,相比指针少了一个临时的指针的地址。因此函数内部对别名的操作就相当于对原实参操作。

exchange(int &f, int &e),  

{

  int  temp 

temp =f;

f=e,

e=temp

}

exchange(b, d)

执行时
f 的值是b, f的地址是b 的地址

e的值是d, e的地址是 d 的地址

执行后

 f的值是c的值, f 的地址还是原来b的地址 b的地址中变成c的值了

e的值变为d的值, e的地址还是原来b的地址, c的地址中变成b的值了,

在数值层面上交换了。

11. 引用和指针相结合,产生了指针类型的引用 int *&f  它的意思是f和一个指针有相同的地址和值。

exchange(int *&f, int *&e),  

{

  int  temp 

temp =f;

f=e,

e=temp

}

exchange(a, c)  注意里面一定要指针

执行时   f  就相当于指针  a

e 就相当于指针c, 

 这样相当于把外面指针直接拿到函数内使用了。 比刚才二级指针效率提升了许多。

引申 

一般的情况是

            二级指针------> 一级指针---->原数据

 要想原数据改变有多种方式

           直接改变 

           利用一级指针做中介 改变一级指针的解引用

           利用二级指针做中介,改变二级指针的解引用, 此时绑定一级指针值和原数据,

           使用指针作为中介的地方都可直接使用引用。去掉中介。


-------------










本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 引用 解引用 取地址 指针 双指针 指针的引用 二级指针 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone

随机推荐

  • AD17无法导出外形层gerber文件

    近日在工作的时候发现Keep OUT层导出的gerber文件 后缀为 GKO 中无内容 导致板厂加工时发现无外形层 发现原因 板子外框线我是在Keep OUT层画的 双击线条发现Keepout选项被勾选 当我把其中一条线条的Keepout选
  • Jquery JqGrid常用方法

    记录平时开发中所用到的JqGrid方法 先附上一个jqgrid 详细介绍的链接 http blog mn886 net jqGrid 1 删除多行数据 var selectedId one grid jqGrid getGridParam
  • 怎么检测硬盘是否有坏道

    硬盘是电脑上非常重要的一个部分 硬盘的好坏也决定了电脑运行的稳定 硬盘最常见的就是出现坏道 一旦有了坏道 将会表现出一些异常的状况 如发出怪音 无法完成分区和格式化的操作 读取文件或运行程序时出错 磁盘占用100 甚至蓝屏等 那怎么检测硬盘
  • Windows下快速启动Kafka以及三种发送消息的方式

    目录 一 下载Kafka 二 启动kafka 2 1 启动kafka前得先启动zk 2 2 启动kafka 三 操作Kafka 3 1 创建 Kafka 主题 Topic 3 2 将信息写入主题 Topic 3 3 读取信息 四 Java实
  • linux下 在终端查看并设置串口

    1 查看串口设备 一般为ttyUSB0 ls dev 2 查看串口的波特率等信息 stty F dev ttyUSB0 a 3 设置串口波特率 数据模式 该命令将串口1 dev ttyUSB0 设置成115200波特率 8位数据模式 stt
  • linux设备驱动的实现与理解

    linux设备驱动的实现与理解 在linux中对字符设备的驱动编写 驱动插入以及使用驱动文件进行逻辑控制 其中这份代码写在嵌入式板中 通过控制io来实现灯的亮灭 但是设备驱动的实现流程与灯无关 大致的流程都体现在代码中 我感觉这份博客我自己
  • 重新出发,找回那个丢失的自己

    时隔一年多了 当初不顾一切的过来 就不要再因为眼前的困难而选择逃避 正视自己的不足 解决它 不忘初心 坚定 believe yourself
  • FreeRTOS入门(05):事件组

    文章目录 目的 基础说明 相关函数 使用演示 总结 目的 事件组是RTOS中相对常用的用于任务间交互的功能 这篇文章将对相关内容做个介绍 本文代码测试环境见前面的文章 FreeRTOS入门 01 基础说明与使用演示 基础说明 事件组 Eve
  • kgdb调试aarch64内核模块

    kgdb调试aarch64内核模块 0 开发环境 1 完善被调试终端的KGDB 2 配置内核 2 1 构建开发环境 2 2设置内核选项 2 3 修改对应模块的优化等级 2 4 内核编译 3 代码修改记录总计 4 文件共享 5 串口复用 6
  • Hibernate Interceptor(拦截器)

    需求 对所有操作数据库的事件 添加audit log 此log持久化到一张单独的audit log表 以供操作人员可以查阅跟踪 方案 Hibernate Interceptor 提供了一个拦截器 使用切面的方法 拦截所有对DB的操作 lik
  • 矩阵违逆的求法_akala啦_新浪博客

    直接求解 求导 令导数为0 结果如下 InvA ATA 1AT 直接求伪逆 InvA inv A A A SVD求解 SVD分解求伪逆 原理和公式 1 SVD分解得到的矩阵 U和V是正交阵 S是对角阵 2 正交阵的逆 转置 3 对角阵的逆
  • 基于javaweb+springboot的宿舍寝室维修上报管理系统(java+SpringBoot+FreeMarker+Mysql)

    管理员 校园管理 楼栋管理 宿舍管理 师生管理 学生管理 辅导员管理 维修管理 维修工管理 维修进度管理 阅览室管理 座位生成等 学生信用积分管理 座位预约统计管理等 学生 登录 修改个人信息 上报宿舍维修信息 查看维修进度 完成维修进度等
  • flutter 常见错误 flutter no devices,No connected devices found;

    原文出处 解决方案 1 使用管理员模式启动AS 部分人试了可以 2 启动Flutter目录下的flutter console bat 执行下面的命令 flutter config android sdk sdk根目录 flutter con
  • Logstash【从无到有从有到无】【L16】使用插件

    目录 1 使用插件 1 1 代理配置 Proxy configuration 1 2 列出插件 Listing plugins 1 3 将插件添加到您的部署中 1 4 高级 添加本地构建的插件 1 5 高级 Using path plugi
  • 销售管理系统java sql_java+sqlserver商品销售管理系统的设计与实现

    摘 要 为解决传统商品销售管理系统操作不便的问题 在My Eclipse 2010 SQL Server 2008环境下 采用B S模式进行商品销售管理系统的设计与开发 实现网络化销售管理 系统主要分为两部分 购物管理部分和管理员管理部分
  • linux 之sed '1!G;h;$!d' file 的详细解释

    sed 1 G h d file 与tac file 命令执行结果相同 都是将行逆序输出 这条命令的详细解释 1 sed简介 sed是面向流的行编辑器 所谓面向流 是指接受标准输入的输入 输出内容到标准输出上 sed编辑器逐行处理文件 或输
  • python机器学习——图像内容分析

    计算机视觉 计算机视觉是一门研究如何使机器 看 的科学 更进一步的说 就是是指用摄影机和电脑代替人眼对目标进行识别 跟踪和测量等机器视觉 并进一步做图形处理 使电脑处理成为更适合人眼观察或传送给仪器检测的图像 计算机视觉包括多个级别的分析
  • Premiere Pro入门

    介绍 Adobe Premiere Pro 简称PR 是最强大的视频编辑软件 可同时创建多个时间轨道 多个视频素材按层遮挡 可对单个素材添加各种效果 例如放缩 移动 旋转 裁剪等 可插入图片遮挡视频素材 并且支持png透明 可添加字幕 可导
  • 新版Spring Boot(11)- Spring Boot 整合NoSQL(1)

    1 整合redis 单测 package com tzb cachespringboot import com tzb cachespringboot model User import org junit jupiter api Test
  • C++ 引用 解引用 取地址 指针 双指针 指针的引用 二级指针

    为了把引用 解引用 取地址 指针 双指针 指针的引用 二级指针 这一块弄清楚 钻研与查阅资料得到如下体会 1 引用与取地址 reference and address 引用的 前面一定有类型符号 否则就不是引用 取地址的 后面一定有变量名称