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++中的引用

引用(C++ 推荐 使用引用技术,因为语法方便。引用的本质是指针常量,但是所有的指针操作编译器都帮我们做了)

引用的基本使用

作用:给变量起别名(两个变量除了名字外是完全相同的)

语法:数据类型 &别名 = 原名;

?

#include?<iostream>

#include?<string>

using?namespace?std;

int?main()

{

????????int?a = 10; // 原名

????????int?&b = a; // 引用(起别名)

????????cout <<?"a = :"?<<?a <<?endl;

????????cout <<?"b = :"?<<?b <<?endl;

????????b = 1001; // 修改别名的内容

????????cout <<?"a = :"?<<?a <<?endl;

????????cout <<?"b = :"?<<?b <<?endl;

????????system("pause");

????????return?0;

}

运行结果:

?

引用的注意事项

1、引用必须初始化

解释:int &b; // 这就是错误的,因为没有经过初始化

2、引用在初始化后,不可以改变(只可以当一个变量的别名,不可以再改成其他变量的别名)

int &b = a;

int &b = c; // 错误,因为b已经是a的别名了,不可以被改成其他变量的别名

引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参(与形参是指针的作用相同)

优点:可以不使用指针来修改实参

#include <iostream>
#include <string>

using namespace std;

// 1、值传递
void SWAP01(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
}

// 2、地址传递
void SWAP02(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

// 3、引用传递(作用和2、地址传递作用相同)
void SWAP03(int &a, int &b) // 引用传递时,传进来的就是实参a和b“本身”(别名),而不是a、b的副本
{
	int temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 10;
	int b = 20;

	SWAP01(a, b); // 1、值传递(形参不修饰实参)
	cout << "SWAP01 a = :" << a << endl;
	cout << "SWAP01 b = :" << b << endl;

	SWAP02(&a, &b); // 2、地址传递(形参会修饰实参)
	cout << "SWAP02 a = :" << a << endl;
	cout << "SWAP02 b = :" << b << endl;

	SWAP03(a, b); // 3、引用传递(形参会修饰实参,作用和2、地址传递一样)
	cout << "SWAP03 a = :" << a << endl;
	cout << "SWAP03 b = :" << b << endl;

	system("pause");
	return 0;
}

运行结果:

引用做函数的返回值

作用:引用可以作为函数的返回值存在

【注意】不要返回局部变量的引用(同“不要返回局部变量的地址”类似)

??????????????函数调用还可以作为左值

#include?<iostream>

#include?<string>

using?namespace?std;

// 引用做函数的返回值

// 1、不要返回局部变量的引用

int& test01() // 引用的方式作为函数的返回

{

????????int?a = 10; //存放在栈区(函数执行完a就被释放)

????????return?a; // 返回局部变量(由于返回值类型为引用,所以这是在返回局部变量a的引用,也就是返回局部变量a的别名)

????????// 注意这种操作是非法的,因为它返回的是局部变量a的引用(别名),也就是说它返回的其实就是a本身(而不是a的值)

}

// 2、函数的调用可以作为左值

int& test02()

{

????????static?int?a = 10; // 存放在全局区,在全部的程序结束后由系统释放

????????return?a; //这种情况就没有问题,因为执行完test02()后,a不会被释放

}

int?main()

{

????????int?&ref = test01(); // 由于返回值类型为引用,所以将引用ref来作为局部变量a的别名

// 等效为 int &ref = a;?但a所在的地址空间已经被释放了,里面的值已经不是10了

// 所以这一步可以看出,int &ref = a;其实是让 ref 与 a 指向同一个地址

????????cout <<?"ref = "?<<?ref <<?endl;

????????int?&ref2 = test02(); // ref2和静态局部变量a指向同一个地址,执行完test02()后a并没有被释放,因此下面的输出是正确的

????????cout <<?"ref2 = "?<<?ref2 <<?endl;

????????cout <<?"ref2 = "?<<?ref2 <<?endl;

????????test02() = 1000; // 返回值为引用类型时,函数调用可以作为左值

// 这句等效为a = 1000;因为test02()返回的就是a,注意不是a的值

????????cout <<?"ref2 = "?<<?ref2 <<?endl;

????????cout <<?"ref2 = "?<<?ref2 <<?endl;

????????system("pause");

????????return?0;

}

运行结果:?

?

引用的本质

本质:引用的本质在C++内部实现是一个指针常量(即常量类型的指针,也即该指针本身就是一个常量)

int &ref = a; // 会自动转换为?int * const ref = &a;?所以ref不能是其他变量的别名(引用一旦初始化后,就不可以发生改变)

#include?<iostream>

#include?<string>

using?namespace?std;

void?func(int?&ref)

{

????????ref?= 100; // 发现ref是引用,自动转成 *ref = 100;

}

int?main()

{

????????int?a = 10;

????????int?&ref = a; // 发现是引用,转换为int * const ref = &a

????????ref = 20; // 发现ref是引用,自动转成 *ref = 20;

????????cout <<?"a = "?<<?a <<?endl;

????????cout <<?"ref = "?<<?ref <<?endl;

????????system("pause");

????????return?0;

}

运行结果:

?

结论:C++ 推荐 使用引用技术,因为语法方便。引用的本质是指针常量,但是所有的指针操作编译器都帮我们做了。

常量引用

作用:常量引用主要用来修饰形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参。

#include?<iostream>

#include?<string>

using?namespace?std;

void?showValue(int?&a) // 引用的方式进行接收,即传入的是实参本身

{

????????a?= 1000; // 实参会被修改

????????cout <<?"showValue val = "?<<?a?<<?endl;

}

void?showValue_2(const?int?&a) // 引用的方式进行接收,即传入的是实参本身。但由于加了const修饰,就把引用变成了一个常量

{ // 因此形参引用的方式加const是为了防止误操作常见的应用场景)

//a = 1000; // 此操作非法,实参不会被修改

????????cout <<?"showValue val = "?<<?a?<<?endl;

}

int?main()

{

// 常量引用

// 使用场景:用来修饰形参,防止误操作

????????int?a = 10;

// int &ref = 10;// 此操作是非法的,因为右边是常量。被引用的对象必须是在栈区或堆区的数据,而常量位于常量区,即全局区。

????????const?int?&ref = 10; // 此操作是合法的。加上const后,编译器将代码修改为 int temp = 10; const int &ref = temp;

// 也就是说现在的引用是引用一块临时的空间比如temp,但其实我们找不到它的原名(编译器起好了),我们只能通过别名ref去操控它

????????// int &ref是一个指针常量,再加一个const,就既是指针常量,又是常量指针

????????//?ref = 20; // 此操作非法,因为被ref指向的对象已经是一个常量了

????????int?val = 100;

????????showValue(val); // 由于showValue()函数是以引用的方式传递参数的,因此传入的就是实参val本身

????????cout <<?"main() val = "?<<?val <<?endl; // 验证实参是否被修改

????????system("pause");

????????return?0;

}

运行结果:

?

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:31:54  更:2021-07-28 07:34:03 
 
开发: 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年4日历 -2024/4/29 12:30:24-

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