0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++中的const和引用的讨论

电子设计 来源:电子设计 作者:电子设计 2020-12-24 15:35 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

今天给大家分享一下这段时间学习c++的总结学习:c++里面的const关键字和引用。

一、const关键字的总结

1、const什么时候为只读变量,什么时候又是常量呢?

(1)const常量的判别规则:

只用字面量初始化的const常量才会进入符号表

使用其它变量初始化的const常量仍然是只读变量

被volatile修饰的const常量不会进入符号表

在编译期间不能直接确定初始值的const标识符,都被作为只读变量处理

(2)const引用的类型与初始化变量的类型

相同:初始化变量成为只读变量

不同:生成一个新的只读变量

代码版本一:

#include <stdio.h>
int main()

const int x = 1;//直接得到值,进入符号表,但是还是会为 x 分配空间,只不过这个空间 x 没有用而已
const int& rx = x;//rx代表只读变量,这个变量是编译器为x分配而没有使用的空间;引用代表变量的别名,而变量代表一段内存空间的别名,所以引用代表一段内存空间的别名
int& nrx = const_cast<int&>(rx); //消除 rx只读属性,和rx 代表的内存空间相同,同时c++里面的几种类型转换要掌握
nrx=5;
printf("x = %d",x);
printf("rx = %d",rx);
printf("nrx = %d",nrx);
printf("&x = %p",&x);
printf("&rx = %p",&rx);
printf("&nrx = %p",&nrx);

return 0;

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
x = 1
rx = 5
nrx = 5
&x = 0x7ffcc5fa8abc
&rx = 0x7ffcc5fa8abc
&nrx = 0x7ffcc5fa8abc

代码版本二:

#include <stdio.h>
int main()

volatile const int y = 2;// 只读变量,不会进入符号表
int *p = const_cast<int*>(&y);//y被 const修饰,取到的地址也有 const 属性,这里将地址只读属性去掉
*p = 8;
printf("y = %d",y);
printf("p = %p",p);
return 0;

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
y = 8
p = 0x7ffd78559684

代码版本三:

#include <stdio.h>
int main()

volatile const int y = 2;
int *p = const_cast<int*>(&y);
*p = 8;
printf("y = %d",y);
printf("p = %p",p);
const int z = y ;//只读变量
p = const_cast<int*>(&z);
*p= 9;
printf("z = %d",z);
printf("p = %p",p);
return 0;

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
y = 8
p = 0x7ffc5d651250
z = 9
p = 0x7ffc5d651254

代码版本四:

#include <stdio.h>
int main()

char c = 'c';
char& rc = c;
const int& trc = c; // char 类型默认转换为 int;const 引用初始化类型不同,将得到新的只读变量,所以改变 rc 和 trc 没有丝毫关系,从我们的输出结果可以看出来
rc = 'a';
printf("c = %c",c);
printf("rc = %c",rc);
printf("trc = %c",trc);
return 0;

结果输出:

root@txp-virtual-machine:/home/txp# ./a.out
c = a
rc = a
trc = c

二、引用的总结:

1、引用与指针有什么关系,以及如何理解"引用的本质就是指针常量"?

(1)指针是一个常量:

值为一个内存地址,不需要初始化,可以保存不同的地址

通过指针可以访问对应内存地址中的值

指针可以被const修饰成为常量或者只读变量

(2)引用只是一个变量的新名字:

对引用的操作(赋值、取地址等)都会传递到代表的变量上

const引用使其代表的变量具有只读属性

引用必须在定义时初始化,之后无法代表其它变量

(3)从使用c++语言的角度来看:

引用与指针没有任何的关系

引用是变量的新名字,操作引用就是操作对应的变量

(4)从c++编译器的角度来看:

为了支持新概念"引用"必须要一个有效的解决方案

在编译器内部,使用指针常量来实现"引用"

因此"引用"在定义时必须初始化

(5)在工程项目开发中:

当进行c++编程时,直接站在使用的角度来看待引用,与指针毫无关系,引用就是变量的别名

当对C++代码进行调试分析时,一些特殊情况,可以考虑站在C++编译器的角度来看待引用

代码实践:

版本一:

#include <stdio.h>
int a = 2;
struct SV{
int& x;
int& y;
int& z;
};
int main()

int b =4;
int* pc = new int(3) ;
SV sv = {a,b,*pc};
printf("&sv.x = %p",&sv.x);
printf("&sv.y = %p",&sv.y);
printf("&sv.z = %p",&sv.z);
delete pc;
return 0;

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
&sv.x = 0x601050
&sv.y = 0x7ffee11ba794
&sv.z = 0x1cfd010

版本二:

#include <stdio.h>
int a = 2;
struct SV{
int& x;
int& y;
int& z;
};
int main()

int b =4;
int* pc = new int(3) ;
SV sv = {a,b,*pc};
int& array[] = {a,b,*pc};//数组中的每个元素是引用就不可以;error: declaration of ‘array’ as array of references;C++ 天生要支持 C 语言,C 语言中数组中的每个元素在内存中是顺序存放的,地址是递增的,所以在 C++ 中也要兼容这个特性,而在 C++ 中唯有引用数组破快了这个特性,所以说 C++ 中不支持引用数组;&array[1] - &array[0] != Expected ==> 4
printf("&sv.x = %p",&sv.x);
printf("&sv.y = %p",&sv.y);
printf("&sv.z = %p",&sv.z);
delete pc;
return 0;

输出结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:16:14: error: declaration of ‘array’ as array of references
int& array[] = {a,b,*pc};

三、总结:

指针是一个变量

引用是一个变量的新名字

const引用能够生成新的只读变量

在编译器内部使用指针常量实现"引用"

编译时不能直接确定初始值的const标识符都是只读变量

好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。我是txp,下期见!

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 可编程逻辑
    +关注

    关注

    7

    文章

    526

    浏览量

    45307
  • C++
    C++
    +关注

    关注

    22

    文章

    2122

    浏览量

    76714
  • CONST
    +关注

    关注

    0

    文章

    45

    浏览量

    8683
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C/C++条件编译

    条件编译是一种在编译时根据条件选择性地包含或排除部分代码的处理方法。在 C/C++ ,条件编译使用预处理指令 #ifdef、#endif、#else 和 #elif 来实现。常用的条件编译指令有
    发表于 12-05 06:21

    C++程序异常的处理机制

    1、什么是异常处理? 有经验的朋友应该知道,在正常的CC++编程过程难免会碰到程序不按照原本设计运行的情况。 最常见的有除法分母为零,数组越界,内存分配失效、打开相应文件失败等等。 一个程序
    发表于 12-02 07:12

    C/C++代码静态测试工具Perforce QAC 2025.3的新特性

     Perforce Validate  QAC 项目的相对/根路径的支持。C++ 分析也得到了增强,增加了用于检测 C++ 并发问题的新检查,并改进了实体名称和实
    的头像 发表于 10-13 18:11 346次阅读
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>代码静态测试工具Perforce QAC 2025.3的新特性

    技能+1!如何在树莓派上使用C++控制GPIO?

    和PiGPIO等库,C++可用于编程控制树莓派的GPIO引脚。它提供了更好的性能和控制能力,非常适合对速度和精度要求较高的硬件项目。在树莓派社区,关于“Python
    的头像 发表于 08-06 15:33 3584次阅读
    技能+1!如何在树莓派上使用<b class='flag-5'>C++</b>控制GPIO?

    请问如何在C++中使用NPU上的模型缓存?

    无法确定如何在 C++ 的 NPU 上使用模型缓存
    发表于 06-24 07:25

    在OpenVINO™ C++代码启用 AddressSanitizer 时的内存泄漏怎么解决?

    在 OpenVINO™ C++代码启用 AddressSanitizer 时遇到内存泄漏: \"#0 0xaaaab8558370 in operator new(unsigned
    发表于 06-23 07:16

    主流的 MCU 开发语言为什么是 C 而不是 C++

    在单片机的地界儿里,C语言稳坐中军帐,C++想分杯羹?难喽。咱电子工程师天天跟那针尖大的内存空间较劲,C++那些花里胡哨的玩意儿,在这儿真玩不转。先说内存这道坎儿。您当stm32f4的256kRAM
    的头像 发表于 05-21 10:33 780次阅读
    主流的 MCU 开发语言为什么是 <b class='flag-5'>C</b> 而不是 <b class='flag-5'>C++</b>?

    带你在单片机编程熟练使用const(可下载)

    C 语言关键字 const 举足轻重,我们今天就深度聊一聊 const 的定义和实际应用,让它 不再是迷C 语言中
    发表于 04-01 14:18 3次下载

    C++学到什么程度可以找工作?

    C++学到什么程度可以找工作?要使用C++找到工作,特别是作为软件开发人员或相关职位,通常需要掌握以下几个方面: 1. **语言基础**:你需要对C++的核心概念有扎实的理解,包括但不限于指针、内存
    发表于 03-13 10:19

    创建了用于OpenVINO™推理的自定义C++和Python代码,从C++代码获得的结果与Python代码不同是为什么?

    创建了用于OpenVINO™推理的自定义 C++ 和 Python* 代码。 在两个推理过程中使用相同的图像和模型。 从 C++ 代码获得的结果与 Python* 代码不同。
    发表于 03-06 06:22

    为什么无法在运行时C++推理读取OpenVINO™模型?

    使用模型优化器 2021.1 版OpenVINO™转换模型 使用 Runtime 2022.3 版本在 C++ 推理实现 ( core.read_model()) 读取模型OpenVINO™并
    发表于 03-05 06:17

    基于OpenHarmony标准系统的C++公共基础类库案例:ThreadPoll

    1、程序简介该程序是基于OpenHarmony标准系统的C++公共基础类库的线程池处理:ThreadPoll。本案例完成如下工作:创建1个线程池,设置该线程池内部有1024个线程空间。启动5个线程
    的头像 发表于 02-10 18:09 600次阅读
    基于OpenHarmony标准系统的<b class='flag-5'>C++</b>公共基础类库案例:ThreadPoll

    Spire.XLS for C++组件说明

    Spire.XLS for C++ 是一款专业的 C++ Excel 组件,可以用在各种 C++ 框架和应用程序。Spire.XLS for C+
    的头像 发表于 01-14 09:40 1299次阅读
    Spire.XLS for <b class='flag-5'>C++</b>组件说明

    EE-112:模拟C++的类实现

    电子发烧友网站提供《EE-112:模拟C++的类实现.pdf》资料免费下载
    发表于 01-03 15:15 0次下载
    EE-112:模拟<b class='flag-5'>C++</b><b class='flag-5'>中</b>的类实现

    运动控制卡周期上报实时数据IO状态之C++

    使用C++进行运动控制卡的周期上报功能实现
    的头像 发表于 12-17 13:59 1533次阅读
    运动控制卡周期上报实时数据IO状态之<b class='flag-5'>C++</b>篇