IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++-引用 -> 正文阅读

[C++知识库]C++-引用

引用

引用(Reference)是 C++语言相对于 C语言的又一个扩充,类似于指针,只是在声明的时候用&取代了*。

引用可以看做是被引用对象的一个别名,在声明引用时,必须同时对其进行初始化。引用的声明方法如下:

类型标识符 &引用名 = 被引用对象
//C++引用实例
int a = 10;
int &b = a;//b的地址指向了a,相当于b中存放了a的地址
cout<<a<<" "<<b<<endl;
cout<<&a<<" "<<&b<<endl;

如果我们不希望通过引用来改变原始变量的值时,我们可以按照如下的方式声明引用:

const 类型标识符 & 引用名 = 被引用的变量名
//这种方式我们称为常引用
//不能通过常引用来修改原始值
int a = 10;
const int &b = a;
&b = 20; //lvalue required as left operand of assignment,可以将&b看作一个常量
b = 20;   //assignment of read-only reference  b
a = 20;

我们声明 b 为 a 的常引用,之后尝试通过 b 来修改 a 变量的值,结果编译报错。虽然常引用无法修改原始变量的值,但是我们仍然可以通过原始变量自身来修改原始变量的值,如例 3 中,我们用a=20;语句将 a 变量的值由 10 修改为 20,这是没有语法问题的。

函数引用参数

如果我们在声明或定义函数的时候将函数的形参指定为引用,则在调用该函数时会将实参直接传递给形参,而不是将实参的拷贝传递给形参。如此一来,如果在函数体中修改了该参数,则实参的值也会被修改。这跟函数的普通传值调用还是有区别的。

#include<iostream>
using namespace std;
void swap(int &a, int &b);
void swap1(int a, int b)//在这里相当于将a,b的的复制体传了进来,交换的只是复制体的值,
{
    int temp = a;
    a = b;
    b = temp;
}
int main()
{
    int num1 = 10;
    int num2 = 20;
    cout<<num1<<" "<<num2<<endl;//10.20
    swap(num1, num2);
    cout<<num1<<" "<<num2<<endl;//20.10
    swap1(num1, num2);
    cout<<num1<<" "<<num2<<endl;//照理来说应该是10.20,但是实际输出为20.10
    return 0;
}

void swap(int &a, int &b)//在这里相当于将a,b的地址传了进来,修改的时候是修改的地址内的内容
{
    int temp = a;
    a = b;
    b = temp;
}

函数引用返回值

在 C++ 中,非 void 型函数需要返回一个返回值,类似函数形参,我们同样可以将函数的返回值声明为引用。普通的函数返回值是通过传值返回,即将关键字 return 后面紧接的表达式运算结果或变量拷贝到一个临时存储空间中,然后函数调用者从临时存储空间中取到函数返回值

#include<iostream>
using namespace std;
int valplus(int &a);
int main()
{
    int num1 = 10;
    int num2;
    num2 = valplus(num1);
    cout<<num1<<" "<<num2<<endl;
    return 0;
}
int valplus(int &a)//这里也是一样的道理,因为传的是a的地址,在函数内发生的a = a + 5,真实的修改了a的值,如果传的是int valplus(int a)就不能修改a的值,只是返回值还是15
{
    a = a + 5;
    return a;
}

valplus() 函数采用的是普通的传值返回,也即将变量 a 的结果加上 5 之后,将结果拷贝到一个临时存储空间,然后再从临时存储空间拷贝给 num2 变量。

当我们将函数返回值声明为引用的形式时,虽然运行结果和上面是相同的,但下面中的 valplus() 函数在将 a 变量加上 5 之后,其运算结果是直接拷贝给 num2 的,中间没有经过拷贝给临时空间,再从临时存储空间中拷贝出来的这么一个过程。这就是普通的传值返回和引用返回的区别。

#include<iostream>
using namespace std;
int & valplus(int &a);
int main()
{
    int num1 = 10;
    int num2;
    num2 = valplus(num1);
    cout<<num1<<" "<<num2<<endl;
    return 0;
}
int & valplus(int &a)//这里直接取了函数的地址,跳过了临时空间
{
    a = a + 5;
    return a;
}

此外,我们还需要注意一个小问题。如果我们将例 6 中的 valplus() 函数定义成例 7 中所示的形式,那么这段程序就会产生一个问题,变量 b 的作用域仅在这个 valplus() 函数体内部,当函数调用完成,b 变量就会被销毁。而此时我们若将 b 变量的值通过引用返回拷贝给变量 num2 的时候,有可能会出现在拷贝之前 b 变量已经被销毁,从而导致 num2 变量获取不到返回值。虽然这种情况在一些编译器中并没有发生,但是我们在设计程序的时候也是应该尽量避免这一点的。

我们就是为了避免这一点才采用的引用传递参数。普通的传值返回则不存在这样的问题,因为编译器会将返回值拷贝到临时存储空间后再去销毁 b 变量的。

int & valplus(int a)
{
    int b = a+5;
    return b;//我们定义了局部变量b,可能在函数调用完后b的空间会销毁,有可能会收不到b的返回
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-13 12:37:21  更:2021-12-13 12:38:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:10:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码