C++语言基础(8)-引用
(重要)使用引用的一些注意点:
1.引用不能绑定临时数据,也不能绑定任何无法获取内存地址的常量,表达式,或值,常引用除外。
第一种写法:(错误)
int func_int(){ int n = 100; return n; } int main(){ int m = 100, n = 36; int &r1 = m + n; int &r2 = m + 28; int &r3 = 12 * 3; int &r4 = 50; int &r5 = func_int(); return 0; }
第二种写法:
bool isOdd(int &n){ if(n/2 == 0){ return false; }else{ return true; } } int main(){ int a = 100; isOdd(a); //正确 isOdd(a + 9); //错误 isOdd(27); //错误 isOdd(23 + 55); //错误 return 0; }
第三种写法(正确)
int func_int(){ int n = 100; return n; } int main(){ int m = 100, n = 36; const int &r1 = m + n; const int &r2 = m + 28; const int &r3 = 12 * 3; const int &r4 = 50; const int &r5 = func_int(); return 0; }
第四种写法:(正确)
bool isOdd(const int &n){ //改为常引用 if(n/2 == 0){ return false; }else{ return true; } } int a = 100; isOdd(a); //正确 isOdd(a + 9); //正确 isOdd(27); //正确 isOdd(23 + 55); //正确
为什么加了const就可以?这是因为将常引用绑定到临时数据时,编译器采取了一种妥协机制:编译器会为临时数据创建一个新的、无名的临时变量,并将临时数据放入该临时变量中,然后再将引用绑定到该临时变量。注意,临时变量也是变量,所有的变量都会被分配内存。
2.const修饰引用时三种写法的区别:
第一种写法(错误)
int a = 20; int & const r = a;
第二种写法(正确)
int a = 20; int const &r = a;
第三种写法(正确)
int a = 20; const int &r = a;
上述三种写法中,第一种写法是严重错误的。因为引用在定义时就必须初始化,并且以后也要从一而终,不能再指向其它数据,这也就意味着r本来就不能改变指向,加上const纯属多此一举。
第二种写法和第三种写法本质上是一样的,在定义引用时加上const限制,目的都是不希望通过引用来修改原始数据的值。
一.引用的基本用法
#include <iostream> using namespace std; int main(){ int a = 99; int &b = a; cout<<a<<", "<<b<<endl; cout<<&a<<", "<<&b<<endl; return 0; }
运行结果:
99, 99
0x28ff44, 0x28ff44
如果不希望通过引用修改原始数据的值,可以在定义时添加const限制:
const int &b = a; // 或 int const &b = a;
注意:引用在定义时需要添加&
,在使用时不能添加&
,使用时添加&
表示取地址
二.引用作为函数参数
#include <iostream> using namespace std; void swap3(int &a, int &b); int main(){ int num1, num2; cout<<"Input two integers: "; cin>>num1>>num2; swap3(num1, num2); cout<<num1<<" "<<num2<<endl; return 0; } void swap3(int &a, int &b){ int temp = a; a = b; b = temp; }
运行结果:
Input two integers: 12 34
12 34
Input two integers: 88 99
99 88
Input two integers: 100 200
200 100
三.引用作为函数返回值
引用除了可以作为函数形参,还可以作为函数返回值,请看下面的例子:
#include <iostream> using namespace std; int &plus10(int &n){ n = n + 10; return n; } int main(){ int num1 = 10; int num2 = plus10(num1); cout<<num1<<" "<<num2<<endl; return 0; }
运行结果:
20 20
注意:在将引用作为函数返回值时应该注意一个小问题,就是不能返回局部数据(例如局部变量、局部对象、局部数组等)的引用,因为当函数调用完成后局部数据就会被销毁,有可能在下次使用时数据就不存在了,C++ 编译器检测到该行为时也会给出警告。
因此像下面的写法是不正确的:
#include <iostream> using namespace std; int &plus10(int &n){ int m = n + 10; return m; //返回局部数据的引用 } int main(){ int num1 = 10; int num2 = plus10(num1); cout<<num2<<endl; int &num3 = plus10(num1); int &num4 = plus10(num3); cout<<num3<<" "<<num4<<endl; return 0; }
不能将局部变量m返回!因为函数是在栈上运行的,并且运行结束后会放弃对所有局部数据的管理权,后面的函数调用会覆盖前面函数的局部数据。本例中,第二次调用 plus10() 会覆盖第一次调用 plus10() 所产生的局部数据,第三次调用 plus10() 会覆盖第二次调用 plus10() 所产生的局部数据。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库