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++提出了引用

引用变量就是一个别名,也就是是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

引用和指针的区别

引用和指针之间主要有三个不同:

1、 不存在空引用。引用必须连接到一块合法的内存,而指针可以是空指针

2、 一旦引用被初始化为一个对象,就不能被指向到另一个对象。而指针可以在任何时候指向到另一个对象

3、 引用必须在创建时被初始化,而指针可以在任何时间被初始化

对于这三个区别,其实很好理解:由于引用不允许更改指向,所以空引用将没有任何意义,故而产生了第一个区别,而第二个第三个就是基本概念罢了,所以引用和指针最大的区别总结起来就一句话:引用不能修改指向。

引用的作用

由于引用是给变量起别名,所以使用引用可以简化部分函数,下面以swap函数为例

#include <iostream>
void swap(int a, int b){
    int tmp = a;
    a = b;
    b = tmp;
}

此代码中,a与b是形参,而形参的改变不能影响实参的改变,所以此函数不能完成我们的要求

#include <iostream>
void swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

此代码中,a与b是对应实参的地址的拷贝,*a与*b与实参访问同一块地址,所以可以完成交换,但由于此处传的是地址,故函数内部需要解地址,传参时需要传地址,而取地址符&敲起来特别麻烦,所以这个代码就不是一个很好的选择

#include <iostream>
void swap(int& a, int& b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

此代码中,a与b是对应实参的别名,也就是说,形参和实参是同一个东西。a,b不过是你给实参起的外号而已,并且传参时,也不需要取地址,写起来就非常的舒服了。这也是引用的好处之一。

引用的底层实现

?通过反汇编我们可以得知,引用实际上也是一个指针。在底层中,引用和指针的操作原理相同。

事实上,引用就是一个指针常量,也就是不可修改指向的指针。由于这个特性,编译器在处理引用时会自动对该引用对应的指针解地址,这就使得引用在书写时,比较方便,同时也使得引用的大小与指针的大小不相同。

由于编译处理引用时会将其自动解地址。所以,当我们用sizeof去求引用的大小时,我们获取的大小实际是引用所指对象的大小,这也是为什么我们说引用是给变量起别名的原因。而指针的大小与地址总线的数目有关,也就是与环境(硬件)有关。以long为例:64位系统有64个地址总线,每一个地址总线决定一个位,所以也就是64位8字节,而32位(win32/x86)系统有32个地址总线,所以是32位4字节。

引用的细节

引用时发生类型转换

引用在使用时,相当于给变量起别名,所以我们在使用引用的时候,会有一些小小的变化,以下面的代码为例

#include <iostream>

int main()
{
    double d = 12.34;
    int& r = (int)d;

    return 0;
}

此代码,在编译的时候会报错,原因很简单,r是一个int类型的引用,而d是一个double类型的浮点数,在将double类型的数据赋值给int类型时,会产生截断。

在截断的时候,会产生一个与double类型值相同的临时变量,而这个临时变量是不可修改的,而应用指向的对象是可以通过引用来修改的,上面的代码相当于放大了权限,所以编译器会报错,如果我们非要这么做,可以在引用前加上const进行修饰,将其指向的值变成不可修改的,就可以通过编译。

?

我们看到,编译器只在第6行报了错误,这也验证了我们的说法。

引用返回一个销毁的变量

用引用去接受一个销毁的变量时,那么该引用会是一个随机值

#include <iostream>

int& Func()
{
    int n = 0;
    
    //执行的操作
    n++;
    return n;
}

int main()
{
    int& a = Func();
	std::cout << a << "\n";
	std::cout << a << "\n";
	std::cout << a << "\n";
    return 0;
}

运行结果:

我们知道,函数在被调用时,首先会为这个函数创建其对应的栈帧,用来给这个函数开辟空间,使其正常执行,这也是递归深度较深时,栈溢出导致程序崩溃的原因。而函数调用结束后会释放这块空间。

?这里n在函数Func执行结束后被销毁,对应的a访问的地址就变成了一块已经被释放的空间,所以a对应的值就会变为随机值,那么为什么第一次输出会是1呢?

其实,cout也是一个函数,在运算符重载那块我们会详细说明。在cout调用的时候它的栈帧覆盖了Func调用时使用的空间,这就导致这个值从1变成了随机值。

就相当于你去住酒店,你走的时候在酒店里放了个苹果,然后你自己偷偷的复制了一张门卡。当你下一次再去打开那间房子时,你的苹果可能会被酒店的人员整理打扫,苹果就不见了,或者下一个用户在里面放了个梨,你进去没有找到苹果,但是看到了一个梨。这里也是相同的原理。

为了验证我们的说法,我们可以用以下代码进行测试:

#include <iostream>

int& Func()
{
	int n = 0;

	//执行的操作
	n++;
	return n;
}

void Func2()
{
	int c = 100;
}

int main()
{
	int& a = Func();
	std::cout << a << "\n";
	std::cout << a << "\n";
	Func2();
	std::cout << a << "\n";

	return 0;
}

运行结果:

?这里就是由于Func2的栈帧覆盖了Func的栈帧,并且Func2中c的位置与n的地址刚好一样,得到了这样的结果。

如果你在测试这段代码时发现其结果不同,可以看一下自己是否关掉了SDL检查,方法:

项目-->属性-->C/C++-->常规-->SDL检查,点否即可。

当你没有关闭SDL检查时可能得到如下结果:

?请跟据自己的结果进行调试。

最后教大家一个小技巧,如何判断两个函数的栈帧是否重合,在调用时,如果两个函数中要创建的变量数目和需要的大小是相同的,那么这两个函数就有很大的可能使用同一块栈帧,且其中的变量的地址一一对应.

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

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