C++编程:复合数据类型—引用(c++ 复合类型)
liebian365 2025-01-23 18:33 15 浏览 0 评论
我们可以在C++中为数据对象另外起一个名字,这叫做“引用”(reference)。
1. 引用的用法
在做声明时,我们可以在变量名前加上“&”符号,表示它是另一个变量的引用。引用必须被初始化。
int a = 10;
int& ref = a; // ref是a的引用
//int& ref2; // 错误,引用必须初始化
cout << "ref = " << ref << endl; // ref等于a的值
cout << "a的地址为:" << &a << endl;
cout << "ref的地址为:" << &ref << endl; // ref和a的地址完全一样
引用本质上就是一个“别名”,它本身不是数据对象,所以本身不会存储数据,而是和初始值“绑定”(bind)在一起,绑定之后就不能再绑定别的对象了。
定义了应用之后,对引用做的所有操作,就像直接操作绑定的原始变量一样。所以,引用也是一种间接访问数据对象的方式。
ref = 20; // 更改ref相当于更改a
cout << "a = " << a << endl;
int b = 26;
ref = b; // ref没有绑定b,而是把b的值赋给了ref绑定的a
cout << "a的地址为:" << &a << endl;
cout << "b的地址为:" << &b << endl;
cout << "ref的地址为:" << &ref << endl;
cout << "a = " << a << endl;
当然,既然是别名,那么根据这个别名再另起一个别名也是可以的:
// 引用的引用
int& rref = ref;
cout << "rref = " << rref << endl;
cout << "a的地址为:" << &a << endl;
cout << "ref的地址为:" << &ref << endl;
cout << "rref的地址为:" << &rref << endl;
“引用的引用”,是把引用作为另一个引用的初始值,其实就是给原来绑定的对象又绑定了一个别名,这两个引用绑定的是同一个对象。
要注意,引用只能绑定到对象上,而不能跟字面值常量绑定;也就是说,不能把一个字面值直接作为初始值赋给一个引用。而且,引用本身的类型必须跟绑定的对象类型一致。
//int& ref2 = 10; // 错误,不能创建字面值的引用
double d = 3.14;
//int& ref3 = d; // 错误,引用类型和原数据对象类型必须一致
2. 对常量的引用
可以把引用绑定到一个常量上,这就是“对常量的引用”。很显然,对常量的引用是常量的别名,绑定的对象不能修改,所以也不能做赋值操作:
const int zero = 0;
//int& cref = zero; // 错误,不能用普通引用去绑定常量
const int& cref = zero; // 常量的引用
//cref = 10; // 错误,不能对常量赋值
对常量的引用有时也会直接简称“常量引用”。因为引用只是别名,本身不是数据对象;所以这只能代表“对一个常量的引用”,而不会像“常量指针”那样引起混淆。
常量引用和普通变量的引用不同,它的初始化要求宽松很多,只要是可以转换成它指定类型的所有表达式,都可以用来做初始化。
const int& cref2 = 10; // 正确,可以用字面值常量做初始化
int i = 35;
const int& cref3 = i; // 正确,可以用一个变量做初始化
double d = 3.14;
const int& cref4 = d; // 正确,d会先转成int类型,引用绑定的是一个“临时量”
这样一来,常量引用和对变量的引用,都可以作为一个变量的“别名”,区别在于不能用常量引用去修改对象的值。
int var = 10;
int& r1 = var;
const int& r2 = var;
r1 = 25;
//r2 = 35; // 错误,不能通过const引用修改对象值
3. 指针和引用
从上一节中可以看到,常量引用和指向常量的指针,有很类似的地方:它们都可以绑定/指向一个常量,也可以绑定/指向一个变量;但不可以去修改对应的变量对象。所以很明显,指针和引用有很多联系。
(1)引用和指针常量
事实上,引用的行为,非常类似于“指针常量”,也就是只能指向唯一的对象、不能更改的指针。
int a = 10;
// 引用的行为,和指针常量非常类似
int& r = a;
int* const p = &a;
r = 20;
*p = 30;
cout << "a = " << a << endl;
cout << "a的地址为:" << &a << endl;
cout << "r = " << r << endl;
cout << "r的地址为:" << &r << endl;
cout << "*p = " << *p << endl;
cout << "p = " << p << endl;
可以看到,所有用到引用r的地方,都可以用*p替换;所有需要获取地址&r的地方,也都可以用p替换。这也就是为什么把操作符*,叫做“解引用”操作符。
(2)指针的引用
指针本身也是一个数据对象,所以当然也可以给它起别名,用一个引用来绑定它。
int i = 56, j = 28;;
int* ptr = &i; // ptr是一个指针,指向int类型对象
int*& pref = ptr; // pref是一个引用,绑定指针ptr
pref = &j; // 将指针ptr指向j
*pref = 20; // 将j的值变为20
pref是指针ptr的引用,所以下面所有的操作,pref就等同于ptr。
可以有指针的引用、引用的引用,也可以有指向指针的指针;但由于引用只是一个“别名”,不是实体对象,所以不存在指向引用的指针。
int& ref = i;
//int&* rptr = &ref; // 错误,不允许使用指向引用的指针
int* rptr = &ref; // 事实上就是指向了i
(3)引用的本质
引用类似于指针常量,但不等同于指针常量。
指针常量本身还是一个数据对象,它保存着另一个对象的地址,而且不能更改;而引用就是“别名”,它会被编译器直接翻译成所绑定的原始变量;所以我们会看到,引用和原始对象的地址是一样,引用并没有额外占用内存空间。这也是为什么不会有“指向引用的指针”。
引用的本质,只是C++引入的一种语法糖,它是对指针的一种伪装。
指针是C语言中最灵活、最强大的特性;引用所能做的,其实指针全都可以做。但是指针同时又令人费解、充满危险性,所以C++中通过引用来代替一些指针的用法。后面在函数部分,我们会对此有更深刻的理解。
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)