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. 引用的概念

引用C++语言中引入的概念,引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和引用的变量共用同一块内存空间就像一个人既有正名,也会有小名或者外号~

//引用的写法 引用变量类型& 引用变量名 = 引用实体

int main
{
    int a = 0;
    int& b = a;//b为a的引用
    return 0;
}
//引用的类型必须和引用的实体相同

?a,b共用一块内存。

2. 引用的特点

2.1 引用在定义时必须初始化

int main
{
    int a = 10;

    //int& b; 编译不通过
    int& b = a;
}

2.2 一个变量可以有多个引用

int main
{
    int a = 10;
    int& b = a;
    int& c = a;
    int& d = c;
}
// b、c、d都是a的引用

2.3 引用只能引用一个实体,引用后不能再引用其他实体

int main
{
    int a = 10;
    int& b = a;

    int c = 5;
    //b = c 编译不通过
}

3. 常引用

常引用就是在定义引用变量时,在前面加上一个const,和C语言中的const作用一样,将变量可读可写的权限变成只能可读的权限。相当于是权利缩小。

int main
{

    //引用的权利可以和实体相同,或者是缩小,但是不能放大。
    const int a = 10;
    //int& b = a;     实体权力为只读,引用权力放大,所以不正确;
    const int& b = a;
    
    //int& c = 10;    引用可以直接引用整数,但是整数具有常属性,所以权力应该是只读的。
    const int& c = 10;

    double d = 2.2;
    //int& e = d;    低精度类型引用实体时,会发生截断,在给e赋值时,中间会产生临时变量,d先赋值给                
    //               临时变量,再给到e,而临时变量具有常属性,所以引用要用const修饰。
    const int& e = d;
}

可以验证一下上面的第三个例子,e并不是d的引用:?

?在vs2019下,可以看到d和e的地址并不相同,就说明d和e并不使用同一块内存,所以d不是e的引用,间接证明,e赋值给d的时候是产生了临时变量,引用了临时变量。

常引用在函数传参时有时会起到一些作用,要注意引用的权限。?

4. 使用场景

4.1?引用做函数参数

交换数值在C语言中是用指针写的,用起来比较麻烦,在C++中可以用引用传参:

//用指针写的交换数值函数,用解引用,比较麻烦

void swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}


//用引用写的交换数值函数
//引用是实体的别名,所以直接交换两个引用,就是交换两个实体,方便容易理解

void swap(int& x, int& y)
{
    int tmp = x;
    x = y;
    y = tmp;
}

4.2 引用做函数返回值

4.2.1

?引用做函数返回值就是返回n的别名,不会产生新的临时变量。因为n由static修饰,所以n被储存在静态区,就算Count()函数执行完毕,n也不会被销毁。所以ret可以引用n的值。

如果不小心没加static,第一次打印ret也是可以打印出的,但是第二次打印就不能打印出1了。要解释这种现象就要从函数栈帧的角度看待这个问题。1.首先在第一次调用Count()函数时,n为1,这没问题,返回n的别名m(姑且称为m),但是问题是n是局部变量了,Count()函数调用完后n,m会随着它的栈帧一起销毁,为什么ret还能引用m呢?2. 因为函数栈帧只是通常意义上的“销毁”,里面的数据并没有马上销毁,它们仍然存在,只是操作系统不允许再访问了。而ret引用m,访问m是非法访问的!但是是可以访问的,(不允许但是可以,就像上中学时不允许学生谈恋爱,但是仍然有谈恋爱的。。)3. 输出函数也要调用函数栈帧,但是要先传参数,1先被传到了cout函数中,所以能被打印出来,但是这时Count()函数之前的栈帧已经被cout函数调用的栈帧覆盖了,原来n的位置也被覆盖了,所以在第二次调用cout时,ret不再是1了而是随机值!

?4.2.2

这个道理和上面的一样,第一次调用Add得到3,但由于栈帧内的数据仍然存在,所以ret能访问到c,ret引用c的引用d。第二次调用,函数栈帧仍然在原来的地方,不过c变成了11,所以引用d也是11,ret仍然是那一块内存,所以也是11。?

和4.21.相同,第一次可以打印出11,第二次由于刚刚调用了cout,所以属于c的那一块内存被覆盖了,c变成了随机值,因此打印出随机值。?

?为什么在这里可以打印出3,那是因为static修饰c只能被初始化一次!所以后面不管调用多少次答案都会是3。

?如果将c=a+b的代数式和定义c的语句分隔开,那么之后的每次每次都会执行a+b了。

由以上的例子可知: 如果函数返回时,出了函数作用域,如果返回对象还未还给系统,则可以使用引用返回,如果已 经还给系统了,则必须使用传值返回。

4.3 传值传引用,返回值返回引用的效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。传值和引用在作为传参以及返回值类型上效率相差很大

5. 引用和指针的区别

  • 在语法层面来讲引用就是一个别名,没有独立空间,和其引用实体共用同一块空间;
  • 在底层实现方面来讲,引用是有空间的,并且实现方式和指针相同。

汇编语言:?

?虽然牌名不一样,但都是一个厂家生产的~

引用和指针的一些不同之处:

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

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