C++ 笔记(15)— 引用(声明引用、引用作为参数、引用作为函数返回值、const 用于引用)
引用是变量的别名。也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
1. 创建引用
要声明引用,可使用引用运算符 &
,如下面的语句所示:
VarType original = Value;
VarType& ReferenceVariable = original;
有如下变量
int i = 0;
我们可以为 i
声明引用变量,如下所示:
int& r = i;
double& s = d;
在这些声明中, &
读作引用。因此,第一个声明可以读作 r
是一个初始化为 i
的整型引用,第二个声明可以读作 s
是一个初始化为 d
的 double
型引用。下面的实例使用了 int 和 double 引用:
#include <iostream>
using namespace std;int main ()
{// 声明简单的变量int i;double d;// 声明引用变量int& r = i;double& s = d;int& r2 = r;i = 5;cout << "Value of i : " << i << endl;cout << "Address of i : " << &i << endl;cout << "Value of i reference r : " << r << endl;cout << "Address of i reference r&: " << &r << endl;cout << "Address of i reference r2&: " << &r2 << endl;cout << "Value of i reference r : " << r << endl;d = 11.7;cout << "Value of d : " << d << endl;cout << "Value of d reference : " << s << endl;return 0;
}
输出结果:
Value of i : 5
Address of i : 0x7ffe2bf65734
Value of i reference r : 5
Address of i reference r&: 0x7ffe2bf65734
Address of i reference r2&: 0x7ffe2bf65734
Value of i reference r : 5
Value of d : 11.7
Value of d reference : 11.7
其中 r2 是 r 的引用,而 r 又是 i 的引用,所以 r2、r、i 的内存地址是相同的。
2. 引用和指针的区别
引用很容易与指针混淆,它们之间有三个主要的不同:
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
3. 引用的特点
典型的函数声明类似于下面这样:
ReturnType DoSomething(Type parameter);
调用函数 DoSomething( ) 的代码类似于下面这样:
ReturnType Result = DoSomething(argument); // function call
上述代码导致将 argument 的值复制给 parameter,再被函数 DoSomething( ) 使用。如果 argument 占用了大量内存,这个复制步骤的开销将很大。同样,当 DoSomething( ) 返回值时,这个值被复制给 Result。如果能避免这些复制步骤,让函数直接使用调用者栈中的数据就太好了。为此,可使用引用。
可避免复制步骤的函数版本类似于下面这样:
ReturnType DoSomething(Type& parameter); // note the reference&
调用该函数的代码类似于下面这样:
ReturnType Result = DoSomething(argument);
由于 argument 是按引用传递的,parameter 不再是 argument 的拷贝,而是它的别名。
#include <iostream>
using namespace std;void getSequare(int& a);int main ()
{int a = 10;cout << "&a is " << &a << endl;getSequare(a);cout << "&a is " << &a << endl;cout << "a sequare is " << a << endl;return 0;
}void getSequare(int& num)
{cout << "&num is " << &num << endl;num *= num;
}
输出结果:
&a is 0x7ffdcf10a7a4
&num is 0x7ffdcf10a7a4
&a is 0x7ffdcf10a7a4
a sequare is 100
函数 getSequare 通过引用参数接受一个要计算其平方的数字,并通过该参数返回结果。如果忘记将参数 num 声明为引用 &
,结果将无法返回到调用函数 main()
,因为 getSequare()
将使用 num 的本地拷贝执行运算,而函数结束时该拷贝将被销毁。通过使用引用,可确保 getSequare()
对 main()
中定义的 num 所在的内存单元进行操作。这样,函数getSequare()
执行完毕后,也可以在 main()
中使用运算结果。
4. const 用于引用
可能需要禁止通过引用修改它指向的变量的值,为此可在声明引用时使用关键字 const
:
int original = 30;
const int& constRef = original;
constRef = 40; // Not allowed: constRef can’t change value in original
int& ref2 = constRef; // Not allowed: ref2 is not const
5. 引用作为参数传递给函数
#include <iostream>
using namespace std;void getSequare(const int& a, int& result);int main ()
{int a = 10;int sequare = 0;getSequare(a, sequare);cout << "sequare is " << sequare << endl; // sequare is 100return 0;
}void getSequare(const int& num, int& result)
{result = num * num;
}
在前一个程序中,使用同一个参数来接受输入和存储结果,但这里使用了两个参数,一个用于接受输入,另一个用于存储运算结果。为禁止修改传入的值,必须使用关键字 const
将其声明为 const
引用,如第 4 行所示。这让 a 变为其值不能修改的参数。
C++ 函数传参:
(1) 将变量名作为实参和形参。这时传给形参的是变量的值,传递是单向的。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同一个存储单元。// 同 c
(2) 传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种通过形参指针可以改变实参的值。// 同 c
(3) C++提供了 传递变量的引用。形参是引用变量,和实参是一个变量,调用函数时,形参(引用变量)指向实参变量单元。这种通过形参引用可以改变实参的值。
引用和指针也很像,它们都不会创建副本,因此效率都很高。它们的主要区别在于:
- 选择成员的时候,引用使用点
.
来查找,而指针则使用->
来查找。 - 指针可能传递一个
NULL
过来,因此在使用前必须检查有效性;引用则必然代表某个对象,不需要做此检查。
6. 引用作为函数返回值
当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。
#include <iostream>
using namespace std;int& getValue();int main ()
{ int& a = getValue();cout << "a is " << a << endl;return 0;
}int& getValue()
{static int ret = 100;return ret;
}
(1)以引用返回函数值,定义函数时需要在函数名前加 &
(2)用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本
其它示例代码:
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{return vals[i]; // 返回第 i 个元素的引用
}// 要调用上面定义函数的主函数
int main ()
{cout << "改变前的值" << endl;for ( int i = 0; i < 5; i++ ){cout << "vals[" << i << "] = ";cout << vals[i] << endl;}setValues(1) = 20.23; // 改变第 2 个元素setValues(3) = 70.8; // 改变第 4 个元素cout << "改变后的值" << endl;for ( int i = 0; i < 5; i++ ){cout << "vals[" << i << "] = ";cout << vals[i] << endl;}return 0;
}
C++ 笔记(15)— 引用(声明引用、引用作为参数、引用作为函数返回值、const 用于引用)相关推荐
- c++函数返回值是一个引用
函数返回值是一个引用的情况: 1.值是如何被返回的: 返回的值用于初始化调用点的一个临时量,该临时量就是函数调用的结果. 如果函数返回引用,则该引用仅是它所引对象的一个别名. 2.不能返回局部对象的引 ...
- python函数的返回值是返回引用吗_python-函数(上):函数返回值、函数调用、前向引用...
编程方法: 1.面向对象:类--class 2.面向过程:过程--def 3.函数式编程:函数--def #python中函数#函数的定义#打印一个佛祖镇楼 -> 一个功能点的解释 defpri ...
- 函数返回值是否使用引用类型的问题:理解引用、返回值
在<对象更有用的玻璃罩--常引用>一文中,介绍了对象作为函数的参数时,推荐使用引用的形式.并且,如果实际参数的值不允许改变时,声明为常引用更佳. 在<第8周-任务1-方案3-复数类中 ...
- 14. 函数返回值为引用?
函数返回值可以是引用吗? 当然可以,只是在函数返回引用的时候需要注意几点.以下给出讨论! 函数在返回值的时候,会产生一个临时变量作为函数返回值的副本:而函数在返回引用的时候,不会产生副本!那么既然是引 ...
- 2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码)
2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码) 1.引用(普通引用) 变量 ...
- “引用作为函数参数”与 “引用作为函数返回值”
一.引用作为函数参数 作为函数参数时引用有两种原因: 1.在函数内部会对此参数进行修改:2.提高函数调用和运行效率. 关于第一点,都知道C++里提到函数就会提到形参和实参.如果函数的参数实质就是形参, ...
- 函数返回值 返回引用
先看看该链接讨论的问题作为热身.http://topic.csdn.net/u/20070616/13/2a6a1739-1a69-4829-a90f-fdb19a61e095.html 函数返回值和 ...
- C++11 右值引用与常量左值引用保存临时变量(函数返回值)的底层分析
右值引用保存临时变量(函数返回值)的问题 :临时变量是右值 1.普通变量接收函数返回值: 2.右值引用变量接收函数返回值: 3.用const int& 和右值引用是一样的效果,只是const ...
- C++ 引用作为函数返回值
(1)以引用返回函数值,定义函数时需要在函数名前加 & (2)用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本. 引用作为返回值,必须遵守以下规则: (1)不能返回局部变量的引用 ...
最新文章
- web开发性能优化---用户体验篇
- Windows API一日一练(1)第一个应用程序
- 配置PIM auto-rp
- 如何识别数据中心的能源浪费?
- 武汉自考本科计算机专业哪个好,2020年武汉自考本科专业有哪些?
- 让div margin属性消失_为什么div里面打一个字之后就会有高度了呢?
- matlab写函数进行坐标正反算,基于matlab的坐标正反算
- 得到节点值的两种方法
- Linux下环境搭建(一)——java、tomcat配置
- 360浏览器:中国为什么没有自主研发的浏览器内核?
- 2.mongoDB 命令
- 2010-10-08在浏览器中兼容+jQuery3
- PHP 9: 表达式
- 朗威计算机保密检查取证工具,保密检查工具(中安兴坤、朗威、中孚)含国保测证书...
- 工程造价步骤_史上最全造价工作流程,全了
- CSS 如何完美地去除表格的 “双线”
- stress模拟CPU使用100%
- 菜鸟吐槽一下hao123
- 几款免费wordpress主题推荐
- 第五章: 项目范围管理
热门文章
- 2022-2028年中国分离膜外壳行业市场调查研究及投资前景预测报告
- 2022-2028年中国钽酸锂单晶行业市场调查分析及投资发展潜力报告
- python 实现桶排序
- IDEA : Git Pull Failed 解决(IDEA中使用stash功能)
- Python中re的match、search、findall、finditer区别正则
- GStreamer 1.18.4稳定的错误修复版本
- 自然语言推理:使用注意力机制
- 2021年大数据Flink(三十三):​​​​​​​Table与SQL相关概念
- 2021年大数据Flink(二):Flink用武之地
- 2021年大数据Spark(五):大环境搭建本地模式 Local