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++之引用怎么用

1.引用的概念

? ? ? ? 引用并不是新定义一个变量,而是给一个已存在的变量取一个别名。编译器并不会为引用变量开辟空间,它和它应用的变量共用一块空间。也就是说引用是同一块变量空间的不同名字

? ? ? ? 格式:类型&? 引用变量名=引用实体

?注意:上面ra的类型还是整形(int),类型并不是int&,对引用进行赋值就是对他引用的实体赋值。

2.引用特性

  • ?引用在定义时必须初始化。否则不知道引用的哪一个
#include<iostream>
using namespace std;

int main(){
	int a=10;
	int& ra;//编译时出错
    return 0;
}
  • 一个变量可以有多个引用。
#include<iostream>
using namespace std;
//这样都是正确的,一块空间的多个命名
int main(){
	int a=10;
	int& ra=a;
	int& rb = a;
	int& rc = ra;
    return 0;
}
  • 应用一旦引用一个实体,再也不能引用其它实体。不然就是赋值。

3.常引用

  • 一个常量的引用也应该是一个常量
#include<iostream>
#include<Windows.h>
using namespace std;

int main(){
	const int a=10;
	//int& ra=a;编译时出错
	const int& ra = a;

	system("pause");
    return 0;
}

原因:变量a是可读不可改写的,引用ra是可读可改写的,如果对ra改写,就会对a产生影响。所以会编译出错。

  • 一个变量也可以用一个常量引用来引用
#include<iostream>
#include<Windows.h>
using namespace std;

int main(){
	int a=10;
	int& ra=a;
	const int& rb = a;//可以用一个常量引用

	system("pause");
    return 0;
}

原因:变量a是可读可改写的,引用rb是可读不可改写的。这是允许的。

  • 还有一种特殊情况,当引用时发生隐式转化,用常引用接受可以。如下
#include<iostream>
#include<Windows.h>
using namespace std;

int main(){
	double a=3.14;
	//int& ra=a;//编译出错
	const int& rb = a;//正确

	system("pause");
    return 0;
}

原因:当发生隐式转化时,会产生一个临时变量,改临时变量先将原来值进行转化,再赋值给新值。重要的原因是,该临时变量具有常量性质(可读不可改写)。所以需要常引用接收。

用上面的例子就是,rb引用a时发生隐式转化,此时会创建一个临时变量tmp,先将a转化为int,再将tmp值赋给rb。

注意是引用的时候发生隐式转化时,提前隐式转化,再引用不需要常引用接收。

#include<iostream>
#include<Windows.h>
using namespace std;

int main(){
	double a=3.14;
	int c = a;//提前转化,再引用
	int& rc = c;//正确

	system("pause");
    return 0;
}

结论:引用时,读写权限可以缩小不可以放大。

4.使用场景

  • 做参数

例如一个简单的交换函数Swap,在C语言中,我们需要进行传址操作,才能实现实参数值的交换,但是在C++中,我们可以使用引用,就可以实现实参的交换。

此时是如何实现交换的呢?

可以这样理解,x是a的引用,y是b的引用,引用就是实体本身,也就是说。x就是a,y就是b,他们发生值交换就是a,b发生值交换。因为这里并没有为x和y开辟空间,形成临时变量。

  • 做返回值

这里有几点值得推敲的地方:

1.这里为什么要用static修饰n,如果不用static修饰会怎么样?

上面返回值为int&引用,在main函数中用引用a来接收。我们知道引用并不开辟空间,所以a并没有开辟空间,而是n的引用,也就是n和a的地址会相同。如果不用static修饰n,则n变量在栈上开辟空间,如果调用一个其它的函数,a的值很有可能会发生改变,这样a的值得不到保障。但是static修饰的变量在静态区存储,值并不会发生改变。如下是不用static修饰的变量:

2.返回值不是引用的,如果想用引用来接收,必须使用常引用。

#include<iostream>
#include<Windows.h>
using namespace std;

int Count(){
	int n = 0;
	n++;
	return n;
}

int main(){
	//int& a = Count();//编译错误
	const int& a = Count();//正确

	system("pause");
    return 0;
}

原因:和隐式转化差不多,当返回的时候,会生成一个临时变量,该临时变量的值等于返回值。并且,该返回值具有常量性质。

3.引用做返回值,也可以不使用引用来接收,这样值就得到了保障。

原因:此时main函数里的a开辟空间,与n无关了,或者说与返回时创建的临时变量无关了,只是将它的值赋给了a。

也可以看成下面这样。b的改变并不会影响ra,a。

#include<iostream>
#include<Windows.h>
using namespace std;

int& Count(){
	int n = 0;
	n++;
	return n;
}

int main(){
	const int a = 10;
	const int& ra = a;
	int b = ra;//此时b与ra,a无关,只是将值赋给了b

	system("pause");
    return 0;
}

总结:函数返回时都会创建一个临时变量,引用返回也会创建一个临时变量,但是这个临时变量并不开辟空间,而是返回值的一个引用。可以用引用接收(不是static修饰的值得不到保证),适用于静态和全局变量。也可以不使用引用接收,只是将值赋给了接收变量,值得到了保障。

返回值不是应用,会创建一个临时变量,会临时开辟空间,并且该临时变量具有常量性质。

5.传值和传引用,返回值和返回引用的效率说明

以值作为参数或者返回值,在传参数和返回期间,函数不会直接传递给实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时拷贝,由上可知要开辟临时空间。因此效率时很地下的,而使用引用作为参数和返回值时,并不需要开辟空间。

因此传值,返回值比传引用和返回引用的效率低。

6.引用和指针的区别

? ? ? ? 在语法概念上,引用没有独立的空间,而是和实体公用一块空间。指针在32位机器下占4字节空间,在64位机器下占8字节空间。

? ? ? ? 在底层实现上,引用实际时有空间的,因为引用时按照指针来实现的。

可以发现,在汇编下,引用和指针实现时一样的。

? ? ? ??指针与引用的不同点:

  1. 引用在概念上是定义一个变量的别名,指针存储一个变量的地址。
  2. 引用在定义时必须初始化,指针没有要求。
  3. 引用在引用一个实体后,不能再引用其它实体,指针在任何时候都可以指向一个同类型的实体。
  4. 没有NULL引用,指针可以指向NULL。
  5. 在sizeof中含义不同,引用的结果是引用类型的大小(int&类型是int)。但是指针始终是地址空间所占字节大小(在32位机器下占4字节空间,在64位机器下占8字节空间)
  6. 有多级指针,没有多级引用。
  7. 访问实体不同,指针需要显式解引用,引用编译器自己处理。
  8. 引用加1,为实体数值加1。指针加1,为加上指向类型的大小。
  9. 引用比指针使用起来相对安全。
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-04 21:12:22  更:2021-07-04 21:13:01 
 
开发: 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年5日历 -2024/5/4 13:06:28-

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