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++】C++引用详解、引用与指针的区别

目录

前言

什么是引用??

引用的本质

引用和指针

? ? ? ??基础定义的对比

? ? ? ? ? ? ? ? 基本类型

? ? ? ? ? ? ? ? 类

? ? ? ? ????????指针?

? ? ? ? ? ? ? ??数组?

? ? ? ? 引用与指针的区别

? ? ? ? ????????初始化区别

? ? ? ? ????????赋值区别

? ? ? ? ????????运算区别?

? ? ? ? 小结

引用在函数传参中的作用

? ? ? ? 基本类型

? ? ? ? 构造类型?

? ? ? ? 小结?

总结


前言

? ? ? ? 本教程会涉及到汇编的知识,看不懂没关系,知道结论即可。

? ? ? ? 使用到的工具是vs2010。

什么是引用??

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

? ? ? ? 演示如下:

? ? ? ? 那么怎么证明ref是a的别名呢????????

? ? ? ? 我们知道,别名和本体指的是同一个东西,所以操作ref应该就是操作a,如下:

? ? ? ? 运行,如果ref和a的值一直都是一样的,就代表ref是a的别名,和a是同一个东西

? ? ? ? 如下:

? ? ? ? 观点证明成功!?

引用的本质

? ? ? ? 代码:

? ? ? ? 断点、调试、ALT+8反汇编:

? ? ? ? ?通过汇编可以看出,引用的本质就是取地址

引用和指针

? ? ? ? 引用和指针还是有区别的,我认为引用就是一个弱化了的指针。

? ? ? ??基础定义的对比

? ? ? ? 先来对比基础变量的定义对比,引用和指针的区别。

? ? ? ? ? ? ? ? 基本类型

? ? ? ? 代码如下:

#include <stdio.h>
#include <Windows.h>

int main()
{
	int a = 10;							// 此处下断点
	int& ref = a;						// ref就是a的别名

	int b = 10;
	int* pb = &b;
	
	system("pause");
	return 0;
}

? ? ? ? 断点、编译、调试、ALT+8转到反汇编:

? ? ? ? 可以看到,引用类型在基本类型定义对象起别名时和指针取地址没有区别?。

? ? ? ? ? ? ? ? 类

? ? ? ? 代码如下:

#include <stdio.h>
#include <Windows.h>

class Base
{
public:
	int x;
	int y;
};

int main()
{
	
	Base a = {2,3};							// 此处下断点
	Base& ref = a;

	Base b = {3,4};
	Base* pb = &b;

	system("pause");
	return 0;
}

????????断点、编译、调试、ALT+8转到反汇编:

? ? ? ? 一样没有区别。

? ? ? ? ????????指针?

? ? ? ? 代码如下:

#include <stdio.h>
#include <Windows.h>

int main()
{
	int a = 3;								// 此处下断点
	int* pa = &a;
	int*& ref = pa;							// pa指针的别名

	int b = 3;
	int* pb = &b;
	int** ppb = &pb;						// 二级指针取一级指针的地址

	system("pause");
	return 0;
}

?????????断点、编译、调试、ALT+8转到反汇编:

? ? ? ? 还是一样。

? ? ? ? ? ? ? ??数组?

? ? ? ? 代码如下:

#include <stdio.h>
#include <Windows.h>

int main()
{
	int arr[] = {1,2,3};					// 定义一个整型数组有三个成员		// 此处下断点
	int(&ref)[3] = arr;						// ref是arr的别名

	int bar[] = {1,2,3};
	int(*pbar)[3] = &bar;					// 定义数组指针取数组的地址

	system("pause");
	return 0;
}

????????断点、编译、调试、ALT+8转到反汇编:

? ? ? ? 还是一模一样。

? ? ? ? 那么引用就是指针吗?

? ? ? ? 先不急着下结论,我们这只是比较了定义对象的时候底层区别,其他的操作还没有对比。

? ? ? ? 引用与指针的区别

? ? ? ? ????????初始化区别

? ? ? ? 1、引用必须赋初始值,指针可以不用但不建议;

? ? ? ? 先看指针:

????????编译通过?

? ? ? ? 再看引用:

? ? ? ? 可以看到,引用不赋初始值是无法编译通过的。

? ? ? ? 为什么指针不建议不初始化,因为这可能会导致野指针问题。

? ? ? ? 2、引用只能指向一个变量从一而终;

? ? ? ? 先看指针:

? ? ? ? 编译通过

? ? ? ? 再看引用:

? ? ? ? 编译通过了,观点错了吗?

? ? ? ? 别急,输出一下看看:

? ? ? ? 执行:

? ? ? ? 可以看到ref还是a的别名,根本就没有变成b的别名

? ? ? ? 那么为什么可以编译通过呢?

? ? ? ? ?

????????ref = b;并不是ref变成了b的别名,因为b本身就是一个值,所以这一步只是将b赋值给ref,同时因为ref是a的别名,所以a也修改了。

? ? ? ? ????????赋值区别

????????对引用赋值时对其指向的变量赋值,而并不是修改引用本身的值

? ? ? ? 我们先来看指针

? ? ? ? 我们转到汇编看看底层是怎么操作的:

? ? ? ? 再来看引用:

? ? ? ? 查看汇编:

? ? ? ? 这也就验证了,给引用赋值就是给引用的变量赋值;但是给指针赋值就是真的给指针赋值了?

? ? ? ? ????????运算区别?

????????对引用做运算,就是对其指向的变量做运算,而不是对引用本身做运算

? ? ? ? 先看指针:

? ? ? ? 汇编:

? ? ? ? 再看引用:

?

? ? ? ? 汇编:

? ? ? ? 还有一点:

? ? ? ? 如果引用的本体不能加减,那么引用也不能加减;

? ? ? ? 我们知道,如果类中没有重载++运算符的话,那么类的对象是不能++的,通过这一点来进行实验,如下:

? ? ? ? 先看指针:

#include <stdio.h>
#include <Windows.h>

class Base
{
public:
	int x;
	int y;
};

int main()
{
	Base a = {1,2};        //此处断点
	Base* pa = &a;
	pa++;

	system("pause");
	return 0;
}

? ? ? ? 查看反汇编:

? ? ? ? 再看引用:?

? ? ? ? 虽然Base& ref = a;就是ref取a的地址,和指针没有什么区别,但是ref是引用,引用就是别名,他和a就是同一个东西。a这个对象类的定义中没有重载++操作符,所以a不能++,所以他的别名(他自己)也不能++;?

? ? ? ? 小结

? ? ? ? 1、引用必须赋初始值

? ? ? ? 2、引用只能指向一个变量,从一而终

? ? ? ? 3、对引用赋值时对其指向的变量赋值,而并不是修改引用本身的值

? ? ? ? 4、对引用做运算,就是对其指向的变量做运算,而不是对引用本身做运算

? ? ? ? 5、引用和引用指向的变量是同一个东西,引用指向的变量不能做的运算,引用也不可以

引用在函数传参中的作用

? ? ? ? 基本类型

? ? ? ? 直接看代码:

#include <stdio.h>
#include <Windows.h>

void plus(int& ref)
{
	ref++;
	return ;
}

int main()
{
	int i = 10;
	plus(i);				// 此处下断点

	printf("%d\n",i);

	system("pause");
	return 0;
}

? ? ? ? 汇编:

? ? ? ? F11单步步入跟进函数内部查看汇编:

? ? ? ? 可以看到,引用也可以像指针一样使用,使函数内部操作到变量本身。

? ? ? ? 去掉断点执行以下,查看结果:

? ? ? ? 变量值改变,证明上面说法正确。

? ? ? ? 构造类型?

? ? ? ? 代码如下:

#include <stdio.h>
#include <Windows.h>

struct Base
{
	int x;
	int y;
	Base(int x,int y)
	{
		this->x = x;
		this->y = y;
	}
};

void PrintbyRef(Base& ref,Base* pb)
{
	// 通过指针读取
	printf("%d %d\n",pb->x,pb->y);
	// 通过引用读取
	printf("%d %d\n",ref.x,ref.y);
}

int main()
{
	Base b(2,3);

	PrintbyRef(b,&b);			// 注意传参时,引用不不需要取地址	// 此处下断点

	system("pause");
	return 0;
}

? ? ? ? 断点、编译、调试、ALT+8反汇编:

? ? ? ? F11跟进函数内部:

? ? ? ? 小结?

? ? ? ? 可以看到,不论是作为基本类型传参,还是构造类型;引用都可以像指针一样操作到变量本身,只不过是操作不同。

? ? ? ? 其实引用也可以使用类的引用指向普通变量。

? ? ? ? 假设Base是一个类;然后int i = 10定义一个普通变量;

? ? ? ? 可以Base& ref = i;? ? ? ? 这样是可以的

? ? ? ? 但是不建议,也没有必要。

总结

? ? ? ? 通过上面的实验,我们知道了什么是引用,引用其实就是个弱化了的指针;他可以做到很多指针能做到的事情,但是他最终只是一个别名,不能像指针那么灵活。

? ? ? ? 指针和指向的变量可以作为两个东西,指针本身和变量本身;所以指针自身不受变量的约束,可以任意++、--;

? ? ? ? 但引用和指向的变量只能作为一个东西;如果指向的变量可以做运算操作,那么引用也可以;如果指向的变量不能做运算,那么引用也不可以;

? ? ? ? 再次总结一下:

? ? ? ? 1、?通过汇编可以看出,引用的本质就是取地址

? ? ? ? 2、引用必须赋初始值

? ? ? ? 3、引用只能指向一个变量,从一而终

? ? ? ? 4、对引用赋值时对其指向的变量赋值,而并不是修改引用本身的值

? ? ? ? 5、对引用做运算,就是对其指向的变量做运算,而不是对引用本身做运算

? ? ? ? 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-10-17 12:13:43  更:2022-10-17 12:16: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/19 4:02:28-

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