常量const、引用、指针的大杂烩
文章目录
- 1 普通引用
- 1.1 对普通值的普通引用
- 1.2 对常量值的普通引用
- 1.3 对普通指针的普通引用
- 1.4 对常量指针的普通引用
- 1.5 对指针常量的普通引用
- 1.6 对指向常量的指针常量的普通引用
- 2 常量引用
- 2.1 对普通值的常量引用
- 2.2 对常量值的常量引用
- 2.3 对普通指针的常量引用
- 2.4 对常量指针的常量引用
- 2.5 对指针常量的常量引用
- 2.6 对指向常量的指针常量的常量引用
- 3 总结
这标题,是不是听着就头大?常量(const)、引用、指针本来就 C++ 里面三个很头疼的概念,现在把他们合到一起,更想不明白了。没关系,看完本文后,你一定会对这三个概念有更清晰的认识。
首先我们分析分析,这三个合到一起,共能产生多少种不同的组合?一个对象可以是非指针类型(姑且称为一个“值”),也可以是指针类型。其中值可以是普通值,也可以是常量值;指针可以是普通指针、常量指针(指向常量,指针本身可变),指针常量(指针不可变,指向的值可变)、指向常量的指针常量(指针和指向的值都不可变)。所以一个对象可以细分为6种。而引用也有两种,一种是普通引用,一种是常量引用。这样算下来,应该是 6×2=126\times2=126×2=12 种组合了。其中标题“常量引用绑定到指向常量的常量指针”是最复杂的组合。下面我们就逐个讲清楚这些组合,如何定义,有哪些特点。
为不失严谨性,作出以下两点说明:
-
有人说多于12种组合,因为指针可以指向另一个指针,引用也分左值引用和右值引用。没错,但我们这里不考虑多级指针,并只考虑左值引用。
-
有人说少于12种组合,因为一些组合并不合法,无法定义。也没错,但我们不妨称之为“非法组合”。
1 普通引用
1.1 对普通值的普通引用
int i = 1;
int &ri = i;
这是最简单的。ri
就是对普通值 i
的一个普通引用。ri
可以看作 i
的一个别名:我们给函数传 ri
就是在传 i
,修改 ri
的值就是在修改 i
的值。
1.2 对常量值的普通引用
const int ci = 1;
int &rci = ci; // 非法
这是非法的。我们不能把一个常值绑到一个非常量引用上。理由是,如果可以绑定,则可以通过 rci
修改 ci
,而 ci
是常值,这不就矛盾了吗。因此 C++ 规定其为非法。
1.3 对普通指针的普通引用
int i = 1;
int *p = &i;
int *&rp = p;
这是第一个复合类型。怎么理解 rp
的类型名很关键。我们按照由内向外做如下解读:
rp
也是 p
的别名,用 rp
时就是在用 p
。例如通过 rp
可修改 i
的值。
*rp = 10;
std::cout << i << '\n'; // 输出10
1.4 对常量指针的普通引用
int i = 1;
const int *cp = &i;
const int *&rcp = cp;
这次类型名解读和1.3节中的类似,唯一区别是这次指针指向一个 const int
对象。正是这一区别,是我们无法通过 rcp
改变 i
的值了,正如无法通过 cp
改变 i
的值一样。
值得一提的是,因为此例中 i
不是 const int
,所以我们仍然可以改变 i
的值,此时 *cp
和 *rcp
的值也随之变化。
i = 2;
cout << *cp << ' ' << *rcp << '\n'; // 输出2 2
所谓常量指针指向一个常量,仅是指针认为它指向常量,至于实际到底指向什么,常量还是非常量都是可以的。我们称之为指针被欺骗(见2.1节)。如果我们把一开始就把 i
定义成 const int
类型的,就使 cp
变成指向一个真正的常量的指针了。
1.5 对指针常量的普通引用
int i = 1;
int *const pc = &i;
int *&rpc = pc; // 非法
这是第二个非法组合。原因类似,因为指针常量 pc
是顶层 const,我们无法把一个普通的引用绑定到顶层 const上,否则就能通过 rpc
修改一个常量 pc
了,矛盾了。
1.6 对指向常量的指针常量的普通引用
int i = 1;
const int *const cpc = &i;
const int *&rcpc = cpc; // 非法
这是第三个非法组合,原因同上。
普通引用的六种组合到这里就讲完了,总结一下,非法的三种组合都是自己本身就是常量的,而普通引用禁止绑定到常量上,常量只能被常量引用绑定。这就来到下一节了:常量引用。
2 常量引用
2.1 对普通值的常量引用
int i = 1;
const int &cri = i;
把常量引用绑定到普通值上,就好比让常量指针指向一个非常量,都是虚假的绑定/指向,我们可以戏称之为:引用/指针被欺骗了。这里常量引用以为自己绑到了常量上,所以拒绝通过 cri
来修改 i
;但是实际上 i
不是常量,所以可以通过 i
自己修改 i
的,此时 cri
的值也跟着变。
i = 3;
std::cout << cri << '\n'; // 输出3
2.2 对常量值的常量引用
const int ci = 1;
const int &crci = ci;
这才是真正的绑到一个常量上了。这儿我问大家一个问题:对“常量”值进行“常量”引用的时候,明明有两处“常量”,可为什么语句里面只看到一个 const
关键字?可能懂的人觉得这问题很stupid,但是在写一些复杂的声明的时候,真有可能犯迷糊。提示:看看1.2节,对普通值进行常量引用时,语句里有几个 const
关键字?再看看2.1节,对普通值常量引用的语句和本节的声明引用的语句有何不同?
2.3 对普通指针的常量引用
int i = 1;
int *p = &i;
int *const &crp = p;
这个声明引用的语句也有点意思,我们解读一下。
可以看到,这也是个被欺骗的引用。我们不能改 crp
的值,因为它以为自己绑的是常量,不过,它以为它以为的就是它以为的?我们还是可以改 p
,此时 crp
跟着变。另一方面,虽然我们不能改 crp
,但我们可以改 *crp
,因为 crp
指向一个普通的 int
变量。
*crp = 9;
cout << i << '\n'; // 输出9
crp = nullptr; // 非法
p = nullptr; // 合法,p和crp都变成空指针
2.4 对常量指针的常量引用
int i = 1;
const int *cp = &i;
const int *const &crcp = cp;
这个声明和2.3的基本相似,唯一区别在于指针指向的是一个 const int
对象。造成的影响就是不能再改 *crcp
了,但 crcp
仍是被欺骗的引用,因为它绑的是底层 const,而非顶层 const。
*crcp = 9; // 非法
crcp = nullptr; // 非法
cp = nullptr; // 合法,cp和crcp都变成空指针
2.5 对指针常量的常量引用
int i = 1;
int *const pc = &i;
int *const &crpc = pc;
这个引用的声明和2.3节非常像,大家要注意区分,还是思考那个问题,为什么对指针“常量”进行“常量”引用,只出现一个 const
?
我们不能修改 crpc
,也不能修改 pc
。我们可以修改的是 *crpc
,用它来修改 i
是可以的。
*crpc = 3;
cout << i << '\n'; // 输出3
2.6 对指向常量的指针常量的常量引用
他来了他来了,最复杂的它终于来了!
int i = 1;
const int* const cpc = &i;
const int* const &crcpc = cpc;
以上是对声明引用的解读,有了这个解读,是不是就清晰多了。从这么多常量就可以看出来了,它自己不能、也不能通过它进行任何形式的修改。
3 总结
普通引用 | 常量引用 | |
---|---|---|
普通值 | int &ri = i; | const int &cri = i; |
常量值 | int &rci = ci; 非法 | const int &crci = ci; |
普通指针 | int *&rp = p; 可以通过 rp 修改原值,可以修改 rp | int *const &crp = p; 可以通过 crp 修改原值,不能修改 crp 。 |
常量指针 | const int *&rcp = cp; 无法通过 rcp 修改原值,可以修改 rcp | const int *const &crcp = cp; 不能通过 crcp 修改原值,不能修改 crcp 。 |
指针常量 | int *&rpc = pc; 非法 | int *const &crpc = pc; 可以通过 crpc 修改原值,不能修改 crpc |
指向常量的指针常量 | const int *&rcpc = cpc; 非法 | const int* const &crcpc = cpc; 不可以通过 crcpc 修改原值,不能修改 crcpc |
完结撒花~
相关文章:
常量const、引用、指针的大杂烩
文章目录1 普通引用1.1 对普通值的普通引用1.2 对常量值的普通引用1.3 对普通指针的普通引用1.4 对常量指针的普通引用1.5 对指针常量的普通引用1.6 对指向常量的指针常量的普通引用2 常量引用2.1 对普通值的常量引用2.2 对常量值的常量引用2.3 对普通指针的常量引用2.4 对常量…...
宝塔搭建实战php开源likeadmin通用管理移动端uniapp源码(四)
大家好啊,我是测评君,欢迎来到web测评。 上一期给大家分享了pc端的部署方式,今天来给大家分享uniapp端在本地搭建,与打包发布到宝塔的方法。感兴趣的朋友可以自行下载学习。 技术架构 vscode node16 vue3 uniapp vite types…...
Hive的分区表与分桶表内部表外部表
文章目录1 Hive分区表1.1 Hive分区表的概念?1.1.1 分区表注意事项1.2 分区表物理存储结构1.3 分区表使用场景1.4 静态分区表是什么?1.4.1 静态分区表案例1.4.2 分区表练习一1.4.3 分区操作1.5 动态分区表是什么?1.5.1 动态态分区表案例&#…...
和数集团打造《神念无界:源起山海》,诠释链游领域创新与责任
首先,根据网上资料显示,一部《传奇》,二十年热血依旧。 《传奇》所缔造的成绩,承载的是多少人的青春回忆,《传奇》无疑已经在游戏史上写下了浓墨重彩的一笔。 相比《传奇》及背后的研发运营公司娱美德名声大噪&#x…...
小白入门模拟IC设计,如何快速学习?
众所周知,模拟电路很难学。以最普遍的晶体管来说,我们分析它的时候必须首先分析直流偏置,其次在分析交流输出电压。可以说,确定工作点就是一项相当麻烦的工作(实际中来说),晶体管的参数多、参数…...
51单片机——中断系统之外部中断实验,小白讲解,相互学习
中断介绍 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的,中断功能的存在,很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功能之一,是我们学些单片机必须要掌握的。 为了更容易的理解中断概念&…...
如何设计一个秒杀系统
秒杀系统要如何设计? 前言 高并发下如何设计秒杀系统?这是一个高频面试题。这个问题看似简单,但是里面的水很深,它考查的是高并发场景下,从前端到后端多方面的知识。 秒杀一般出现在商城的促销活动中,指定…...
厄瓜多尔公司注册方案
简介: 经济概况与商机 厄瓜多尔是世界上第74大国家,是南美西部国家,与哥伦比亚,秘鲁和太平洋接壤。厄瓜多尔地处世界中心,地理位置优越,地理位置优越-赤道线零纬度,使其成为通往太平洋的理想枢…...
安全渗透环境准备(工具下载)
数据来源 01 一些VM虚拟机的安装 攻击机kali: kali官网 渗透测试工具Kali Linux安装与使用 kali汉化 虚拟机网络建议设置成NAT模式,桥接有时不稳定。 靶机OWASP_Broken_Web_Apps: 迅雷下载 网盘下载 安装教程 开机之后需要登录&am…...
118.(leaflet篇)leaflet空间判断-点与geojson面图层的空间关系(turf实现)
听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>...
目标检测与目标跟踪算法技术汇总
现如今chatgpt的爆火,我也使用了一段时间,问了许多关于人工智能技术的问题,基本是它能够回答了大部分的原理的,至于其人工智能涉及到的算法以及网络,考虑到也没有图,可能在给出这类回答上,是不太…...
Linux 系统启动过程
过去几十年,公用事业行业发生了重大变化。能源需求的转变导致企业利润率的波动,但不是运营成本的波动。 许多公用事业公司通过后勤部门流程自动化来削减成本,比如招采流程自动化。 在招采活动中,人工招采会产生盲点。由于公共事业…...
【每日一题Day118】LC1124表现良好的最长时间段 | 前缀和+单调栈/哈希表
表现良好的最长时间段【LC1124】 给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」,意味在这段时间内&#…...
vue使用nprogress(进度条)
目录 1.安装 2.引入 3.配置 4.使用 5.使用场景 6.改变颜色 1.安装 npm install --save nprogress2.引入 import NProgress from nprogress import nprogress/nprogress.css3.配置 NProgress.configure({easing: ease, // 动画方式,和css动画属性一样&#…...
@NotNull 、@NotBlank、@NotEmpty区别和使用
引言 今天在使用validation校验的时候,发现了使用校验不起作用,一时间有点摸不到头绪,就看了一下同事提交的代码,发现了问题在用NotNull用法,用的有些错误,所以在这里讲一下NotNull、NotBlank、NotEmpty区…...
Nacos——Nacos简介以及Nacos Server安装
资料来源:02-Nacos配置管理-什么是配置中心_哔哩哔哩_bilibili nacos记得下载2.x版本的,负责以后新建配置的时候会出现“发布错误,请检查参数是否正确”错误!!!! 目录 一、Nacos简介 1.1 四…...
Presto 文档和笔记
1. Presto Presto 官网 Presto 文档 2. 配置 3.1 node 配置 cat etc/node.properties # Generated by Apache Ambari. Fri Feb 10 14:52:10 2023node.data-dir/mnt/bmr/presto/data node.environmentproduction node.idbmr-master-4b7cbaa3.2 jvm 配置 cat etc/jvm.confi…...
大尺度衰落与小尺度衰落
一. 大尺度衰落 无线电磁波信号在收发天线长距离(远大于传输波长)或长时间范围发生的功率变化,称为大尺度衰落,一般可以用路径损耗模型来描述,路径损耗是由发射功率在空间中的辐射扩散造成的,根据功率传输…...
完美解决:重新安装VMware Tools灰色。以及共享文件夹的创建(centos8)
解决:重新安装VMware Tools灰色问题:重新安装VMware Tools灰色解决方案-挂载VMware中的linux.iso1. vmtools的linux.iso挂载及安装2. 共享文件夹的创建及配置问题:重新安装VMware Tools灰色 发现一个小问题,我的vm虚拟机安装后发…...
达梦数据库作业管理
一、基本功能 作业系统大致包含作业,警报,操作员三部分。 作业可运行DMPL/SQL脚本,定期备份数据库,检查等。可定时执行,也可通过警报触发执行,可产生警报通知用户状态。一个作业由多个步骤组成,…...
数据结构-考研难点代码突破(C++实现树型查找-二叉搜索树(二叉排序树))
文章目录1.二叉搜索树基本操作二叉搜索树的效率分析2. C实现1.二叉搜索树基本操作 二叉排序树是具有下列特性的二叉树: 若左子树非空,则左子树上所有结点的值均小于根结点的值。若右子树非空,则右子树上所有结点的值均大于根结点的值。左、…...
emqx异常处理
启动异常 通过解压tar压缩包安装后通过 ./bin/emqx start 启动报错 WARNING: Default (insecure) Erlang cookie is in use. WARNING: Configure node.cookie in /opt/emqx/etc/emqx.conf or override from environment variable EMQX_NODE__COOKIE NOTE: Use the same config…...
Web前端:开始学习ReactJS需要知道什么?
毫无疑问,ReactJS是前端开发者中最著名的库之一,它的受欢迎程度与日俱增。用ReactJS构建的网站看起来非常棒,大多数开发新手都被它吸引住了。然而,许多新人和有经验的开发人员在没有首先了解先决条件的情况下,就直接用…...
卡诺图化简
1.相关概念 最小项:函数的某个乘积项包含了函数的全部变量(原变量或反变量的形式),且每个变量仅出现一次,则这个乘积项为该函数的一个标准积项。 最小项中的原变量记为1,反变量记为0,当变量顺序…...
带你了解软件测试是做什么的
软件测试是互联网技术中一门重要的学科,它是软件生命周期中不可或缺的一个环节,担负着把控、监督软件的质量的重任。 人才稀缺,对于求职者来说就意味着机会。但是很多想学习软件测试的人对这个学科并不了解,也不知道该如何学习&a…...
企业电子招投标采购系统源码之功能模块功能描述
功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力,为外…...
职场中的高手,是如何高质量解决问题?
职场总会遇见很多新问题,高手会从容应对,因为他们学习了一套通 用理论,可以处理工作当中的大部分内容,剩下的一部分能够用快速 提问的方式找到思路。 记得几年前有个同事 A,下午四点多项目突然丢过来一个活,…...
报表生成工具Stimulsoft中的电子签名和 PDF 数字签名
Stimulsoft Reports 是一款报告编写器,主要用于在桌面和Web上从头开始创建任何复杂的报告。可以在大多数平台上轻松实现部署,如ASP.NET, WinForms, .NET Core, JavaScript, WPF, Angular, Blazor, PHP, Java等,在你的应用程序中嵌入报告设计器…...
【Hello Linux】Linux环境下写的第一个程序 -- 进度条
作者:小萌新 专栏:Linux 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:写出Linux中的第一个小程序 进度条 进度条小程序行缓冲区概念\r 和 \n进度条代码和演示行缓冲区概念 我们首先用两段代码来感受下行缓…...
【基础】性能测试,从0到实战(手把手教,非常实用)
一、性能基础 什么是性能测试--->本质? 基于协议来模拟用户发送的请求(业务模拟),对服务器形成一定负载。关注点:时间性能、空间性能与界面无关 性能测试分类 性能测试(狭义) 性能测试方法是通过模…...
p2p网贷网站建设方案/seo的基础优化
一、 先安装 orcale10.1客户端 setup右键属性,按下图设置 net manager 设置,不设置 pl/sql developer没办法连接 二、再安装 pl/sql developer 有了 net manager 设置 下面才自动出现,选择连接...
17网站一起做网店 每日新款/百度seo关键词排名优化教程
linux 安装ibus,中文输入法 IBUS输入法安装和设置 IBus是一个框架,支持多种输入法。 问题1:Ubuntu系统选择自带的拼音输入法是错误的,它默认无法输入中文及中文词组,请独立安装其他基于IBus的输入法 问题2࿱…...
网站如何优化关键词排名/seo排名培训
783. 二叉搜索树节点最小距离 难度简单106 给定一个二叉搜索树的根节点 root,返回树中任意两节点的差的最小值。 示例: 输入: root [4,2,6,1,3,null,null] 输出: 1 解释: 注意,root是树节点对象(TreeNode object),而不是数组。给…...
个人网站可以做企业宣传/域名注册哪个网站好
1.美国大学列表 https://university.graduateshotline.com/ubystate.html 2.获取浏览器 user agent 信息 https://www.whatismybrowser.com/detect/what-is-my-user-agent —————————————————————————————— 转载于:https://www.cnblogs.com/hebol…...
门户网站建设工作管理办法/推广公司有哪些公司
1981年芬兰 Helsink 大学的 TKohonen 教授提出一种自组织特征映射网 (Self-Organizing Feature Map , SOFM ), 又称 Kohonen 网 。 Kohonen 认为 ,一个神经网络接受外界输入模式时, 将会分为不同的对应区域…...
公司介绍模板免费/搜狗seo排名软件
本文为美国卡内基梅隆大学(作者:Ross A. Knepper)的博士论文,共145页。 机器人运动规划的目标是与人类在环境中移动和互动的便捷性、效率相匹配。然而,最先进的机器人规划缺乏人类具备的能力,这些算法的计…...