c++:引用是什么?c++引用详解及使用

引用是什么?

引用&就是取别名. 比如齐天大圣是孙悟空的别名,弼马温也是孙悟空的别名.齐天大圣被困在五行山,那么孙悟空有没有被困呢?

c 复制代码
#include<iostream>
#include<assert.h>
using namespace std;
int main()
{
	int a = 10;
	int& pa = a;  //pa是a的别名
	pa = 20;

	cout << &a << endl;
	cout << &pa << endl;

	cout << a << endl;
	cout << pa << endl;

	return 0;
}

我们发现,引用的别名pa和a的地址,值都是一样的.(齐天大圣就是孙悟空)

引用的使用规范

俗话说:行车不规范,亲人两行泪.引用的使用也是必须要遵守规范的.

引用必须初始化

一个变量可以有多个别名

这个跟我们人一样,可以有多个别名.还可以给别名起别名.比如再给孙悟空的别名齐天大圣起一个别名:猴子.

arduino 复制代码
#include<iostream>
#include<assert.h>
using namespace std;
int main()
{
	int a = 10;
	int& b = a; //b是a的别名
	int& c = b; //c是b的别名,同时也是a的别名
	return 0;
}

引用不能改变指向

这个就好像齐天大圣已经成为孙悟空的别名,不能再被其他人使用. 这个规范是引用和指针之间最大的不同.也是引用无法替代指针的最大原因

c 复制代码
#include<iostream>
#include<assert.h>
using namespace std;
int main()
{
	int a = 10;
	int b = 20;

	int& c = b;//c是b的别名
	c = a;  //这个只是把a的值10赋值给c

	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;
	return 0;
}

我们可以看到c的地址没有发生改变. 在这里我们也可以看到祖师爷设计的初衷.如果没有这个语法 c = a这个语句就会有歧义. 到底将a的值赋值给c,还是将c改为a的别名.

引用的使用场景

引用做参数

ini 复制代码
void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	int x = 19;
	int y = 99;
	Swap(&x, &y);

	cout << "x = " << x << endl;
	cout << "y = " << y << endl;
        
        Swap(x, y);

	cout << "x = " << x << endl;
	cout << "y = " << y << endl;
	return 0;
}

在我们学引用之前,当我们需要交换两个变量的值时要把变量的地址传过去,在Swap函数里面还要不断地解引用,多麻烦. 现在只需要传x和y就行.

引用做返回值

ini 复制代码
class Stack
{
private:
	int* _a;
	int _size;
	int _capacity;
public:
	void Init(int n = 4)
	{
		int* tmp = (int*)malloc(sizeof(int) * n);
		//assert(tmp != nullptr);
		_a = tmp;
		_size = 0;
		_capacity = n;
	}
	void Pushback(int x)
	{

		//...扩容
		_a[_size++] = x;
	}
	int& Get(int pos)
	{
		assert(pos >= 0);
		assert(pos < _size);
		return _a[pos];
	}

};
int main()
{
	Stack st;
	st.Init();
	st.Pushback(1);
	st.Pushback(2);
	st.Pushback(3);
	st.Pushback(4);

	for (int i = 0; i < 4; i++)
	{
		cout << st.Get(i) << " ";
		/*cout << st[i] << " ";*/
	}
	cout << endl;

	for (int i = 0; i < 4; i++)
	{
		if (st.Get(i) % 2 == 0)
		{
			st.Get(i) *= 2; // 修改栈里面的值
		}
	}

	for (int i = 0; i < 4; i++)
	{
		cout << st.Get(i) << " ";
	}
	cout << endl;
	return 0;
}

在栈的基本实现里,如果我们要修改一个数或者得到一个数.我们正常是要写两个函数.但是用了引用做返回值后,我们可以只写一个函数来实现两个功能

野引用的出现

c 复制代码
int& Add(int a, int b)
{
	int c = a + b;
	return c; //c出了Add这个函数就会销毁
}
int main()
{
	int& ret = Add(1, 2); //ret是已销毁空间里面c的别名
	cout << "Add(1, 2) is :" << ret << endl;
	return 0;
}

我们知道,局部变量c在栈区开辟,出了作用域Add就销毁.ret所接收的是一个已销毁空间的值.编译器在销毁的同时很有可能会清理空间.我们访问的是一片未知的区域.

举例: 我们入住酒店(调用函数,开辟空间),离开酒店(销毁空间),打扫酒店房间(清理空间).但是我们在离开时不小心把行李(变量)遗落在房间里面,我们的行李很有可能被清理走了.当我们再次进入房间(再次访问这个空间),我们会发现自己的行李不见了

相关推荐
摆烂小白敲代码4 分钟前
【算法】连通块问题(C/C++)
c语言·数据结构·c++·算法·深度优先·图论·广度优先
白初&10 分钟前
文件上传代码分析
java·c++·python·php·代码审计
香菜大丸11 分钟前
详解 指针函数,函数指针,函数指针函数
开发语言·c++·算法
White graces24 分钟前
Spring MVC练习(前后端分离开发实例)
java·开发语言·前端·后端·spring·java-ee·mvc
Michael_Good1 小时前
【计算机网络】C/C++实现解析Wireshark离线数据包,附源码
c语言·c++·计算机网络
旺代2 小时前
C++设计模式(单例模式)
c++·单例模式·设计模式
kingwebo'sZone3 小时前
ASP.net WebAPI 上传图片实例(保存显示随机文件名)
后端·asp.net
桑榆肖物3 小时前
一个简单的ASP.NET 一致性返回工具库
后端·asp.net
材料苦逼不会梦到计算机白富美5 小时前
贪心算法-区间问题 C++
java·c++·贪心算法