C++中的引用

 套个盾:这只是我自己的学习笔记,有错的地方欢迎大家斧正

1.基本作用:给变量取别名

语法:数据类型 &别名=原名;

2.注意事项:引用必须初始化,且初始化后不可更改

3.引用做函数参数

作用:避免使用指针修改实参 

#include <iostream>
using namespace std;

//交换函数

//1.值传递
void myswap01(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;

	cout << "swap01 x=" << a << endl;
	cout << "swap01 y=" << b << endl;
}
//2.地址传递
void myswap02(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
//3.引用传递
void myswap03(int &a,int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

int main()
{   
	int x = 100;
	int y = 256;

	/*
	myswap01(x, y);
	printf("x=%d\r\n", x);
	printf("y=%d", y);

	//此时主函数的printf打印结果中x、y的值
	//没有改变,因为值传递形参不会修饰实参
	*/

	/*
	myswap02(&x, &y);
	printf("x=%d\r\n", x);
	printf("y=%d", y);

	//地址传递,此时形参可以修饰实参
	*/

	myswap03(x, y);
	printf("x=%d\r\n", x);
	printf("y=%d", y);
	//引用传递,形参也会修饰实参

	system("pause");
	return 0;
}

4.引用做函数的返回值

作用:引用也可以用做函数的返回值

注意事项:不要返回局部变量引用

用法:将函数调用作为左值

我们在声明一个函数时首先要做的就是声明一个函数的返回值类型,比如void、int等等,当然这个返回值在C++中也可以是一个引用。

看这样的一段代码

#include <iostream>
using namespace std;

//引用做函数的返回值
//attention:
//1、不要返回局部变量的引用
int& test01()
{
	int a = 10;//局部变量存放在内存四区中的栈区,执行结束后占用的内存就被释放
	return a;
}


//2、函数的调用在C++中可以作为左值存在

int main()
{
	int& ref=test01();
	cout << "ref=" << ref; 

	system("pause");
	return 0;
}

运行结果:

077d5fb58a8f488c9dea04d4f8d0a0df.png

只有第一次运行结果才是10,因为编译器帮我们对栈中的数据做了一次保留。

如果一个函数的返回值是调用,那么它就可以作为赋值时的左值。话不多说,上代码。

#include <iostream>
using namespace std;

//引用做函数的返回值
//attention:
//1、不要返回局部变量的引用
int& test01()
{
	int a = 10;//局部变量存放在内存四区中的栈区,执行结束后占用的内存就被释放
	return a;
}

//2、函数的调用在C++中可以作为左值存在
int& test02()
{
	static int a = 10;//声明a为静态变量,存放在全局区,程序执行结束后由系统释放
	return a;
}

int main()
{
	//int& ref=test01();
	//cout << "ref=" << ref<<endl; 

	int& ref=test02();
	cout << "ref=" << ref<<endl; 
	cout << "ref=" << ref << endl;

	test02() = 1000;//如果一个函数的返回值是引用,那么她就可以作为赋值的左值

	cout << "ref=" << ref << endl;
	cout << "ref=" << ref << endl;

	system("pause");
	return 0;
}

5.引用的本质

本质:内部实现的指针常量

先上代码:

#include <iostream>
using namespace std;

//发现是引用,转换为int * const ref=&a;
void func(int& ref)
{
	ref = 100;  //ref是引用,转换为*ref=100;
}

int main()
{
	int a = 10;

	int& ref = a;
	//本质上等价于
	//int* const ref = &a;
	//指针常量的指针指向不可更改
	ref = 20;
	//等价于*ref=20;

	cout << "a=" << a << endl;
	cout << "ref=" << ref << endl;

	func(a);
	system("pause");
	return 0;
}

“int a=10;”等价于我们开辟了一块内存为(假设)0x0011的内存空间用来存放一个名叫a的变量,它的值是10.

90d65b573f4148f49c925a345a2f5268.png

“int &ref=a;"相当于int *const ref=&a;这个指针被const修饰,指向为a的存储地址且指向内容不可更改,但我们可以依靠解引用的方式更改这个地址存放的内容。直接赋值ref=20。用起别名的说法也能圆回来,给a起了别名叫ref,然后给ref赋值为20。

e36e27c0bd1647d5aefa71c1c1ed09a5.png

输出结果:

cb2859666ca2466f87169f3c183f5cb7.png

6.常量引用

作用:修饰形参,防止误操作。在函数形参列表中,可以加const修饰形参,防止形参改变实参。

知识储备:

int a = 10;
int& ref = a;

这在C++中是一种被允许的操作,因为a作为一个普通的整形变量内存地址是可操作的。

int& ref = 10;

但这样就不行了,“10”并不是一个声明过的变量。不过我们可以利用const关键字实现这个操作。

/*但在加上const之后
  编译器将代码修改为int temp=10;
  const int &ref=temp;*/
const int& ref = 10;
//现在ref处于只读状态

下面开始正式介绍。

#include <iostream>
using namespace std;

//来给标准IO函数套个壳
void OLED_PrintValue(int& val)
{
	printf("val=%d;\r\n", val);
}


int main()
{    
	
	//常量引用
	//使用场景:修饰形参防止误操作
	//int a = 10;
	//int& ref = a;//a的内存空间可操作
	/*int& ref = 10;
	  不被允许的操作
	*/

	/*但在加上const之后
	  编译器将代码修改为int temp=10;
	  const int &ref=temp;*/
	//const int& ref = 10;
	//现在ref处于只读状态
	
	int x = 100;
	OLED_PrintValue(x);



	system("pause");
	return 0;
}

这样子我们把x通过值传递打印了出来,但如果我们在打印函数中对形参进行了修饰呢?

#include <iostream>
using namespace std;

//来给标准IO函数套个壳
void OLED_PrintValue(int& val)
{
	val = 99;
	printf("val=%d;\r\n", val);
}


int main()
{    
	
	//常量引用
	//使用场景:修饰形参防止误操作
	//int a = 10;
	//int& ref = a;//a的内存空间可操作
	/*int& ref = 10;
	  不被允许的操作
	*/

	/*但在加上const之后
	  编译器将代码修改为int temp=10;
	  const int &ref=temp;*/
	//const int& ref = 10;
	//现在ref处于只读状态
	
	int x = 100;
	OLED_PrintValue(x);
	printf("x=%d\r\n;", x);



	system("pause");
	return 0;
}

这个时候的运行结果是:

53ff83fb54d346728d80323ff8c68f99.png

x作为实参因为引用的原因被形参修饰了,为了避免这个情况, 我们可以再函数体声明形参时加上const,如图所示,此时val成为了一个不可修改的左值。

89dc6b98363e4938af69a53e502ad676.png

/*引用部分完结撒花!*/

 

 

 

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值