值传递、地址传递及引用作为函数参数的区别

本文详细解释了C++中引用的定义、初始化规则以及与值传递、地址传递的区别,尤其是在函数参数中的应用,包括常量引用的使用和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文主要讲述值传递、地址传递和引用作为函数参数的区别,特别介绍引用的定义及注意细节,希望对引用进一步加深理解。

一、引用是什么?

1.引用通俗理解就是给变量起一个别名,对引用的操作与对变量直接操作是一样的
2.引用的常用格式与指针的定义差不多,如下:

int &b = a;//引用,相当于指针b也指向那块内存

3.引用必须初始化,不初始化会报错

int &c;//非法引用,引用必须初始化

4.引用不能重复引用,初始化后不能改变,也就是给一个变量起了一个别名后,不能再拿这个别名去指向别的变量

#include<iostream>
using namespace std;

int main() {

	int a = 10;
	int &b = a;//引用,相当于b也指向那块内存

	int c = 50;
	//int &b = c;//非法引用,引用初始化后不能改变
	
	b = c;//如果此时给b赋值,这时候a也会改变
	
	cout << "引用后b为  " << b<<endl;
	cout << "引用后a为   " << a<<endl;
	cout << "引用后c为   " << c << endl;
	
	system("pause");
	return 0;

}

二、引用作为函数参数,与值传递和地址传递进行比较

这里拿最简单a与b两个值交换作为例子,程序如下图。由结果我们可以看出

1.值传递的函数swap1并不会改变实参,ab的交换只在swap里面进行,相当于main函数的a和b复制一遍传给了swap的形参ab.
2.地址传递的函数swap2会改变实参,由于给swap2传形参时候传入的是地址指针,指向的是a和b的内存空间,在swap2函数里面,两个使得a和b两个地址相互交换了,最后实参也会改变
3.使用引用作为函数参数,同样也会改变实参。他的结构是最简单了,与值传递唯一区别就是定义函数参数时候,变量用引用void swap3(int &a_3, int &b_3) 。就是给a和b起一个别名,用一个指针指向它,ab交换时候就是ab地址交换,本质是定义了一个指针常量int *const a_3=&a_3;

#include<iostream>
using namespace std;

//值传递
void swap1(int a,int b ) {
	int temp = a;
	a = b;
	b = temp;
	cout << "1形参a=   " << a << endl;
	cout << "1形参b=   " << b << endl;
}

//地址传递
void swap2(int *a, int *b) {
	int temp = *a;
	*a = *b;
	*b = temp;
	cout <<"\t"<< "2形参a=   " << *a << endl;
	cout << "\t"<<"2形参b=   " << *b << endl;

}

//引用作为函数的参数
void swap3(int &a_3, int &b_3) {//结构简单,除了参数这里,其他没什么区别。本质上是一个指针常量int *const a_3=&a_3;
	int temp = a_3;
	a_3 = b_3;
	b_3 = temp;
}

int main() {
	int a = 10;
	int b = 20;

	swap1(a, b);
	
	cout << "1实参a=   " << a << endl;//结论:值传递不改变实参
	cout << "1实参b=   " << b << endl;
	
	swap2(&a, &b);//取地址
	cout << "\t" << "2实参a=   " << a << endl;//结论:地址传递改变实参
	cout << "\t" << "2实参b=   " << b << endl;
	
	int a_3 = 10;
	int b_3 = 20;
	swap(a_3, b_3);
	cout << "3实参a=   " << a_3 << endl;//结论:引用做函数参数传递改变实参
	cout << "3实参b=   " << b_3<< endl;


	system("pause");
	return 0;

}

结果图:
实验图

三、引用进阶:引用作函数的返回值

引用作函数的返回值 ,函数可以作为左值来接收,func()的返回值就是引用a。如下程序所示,

1.定义一个引用ret来接收引用函数,int &ret = func();
2. func() = 2000;这时候函数可以作为左值
3. func()的返回值就是引用a,相当于a=2000,ret是a的别名,所以才有ret最后输出2000

#include<iostream>
using namespace std;

int& func() {
	static int a = 10;//静态变量,这个放在全局区,寿命比较长 
	return a;//引用a作为函数的返回值
}

int main() {
	int &ret = func();//定义一个引用ret来接收引用函数

	cout << ret << endl;
	cout << ret << endl;
	
	func() = 2000;//函数可以作为左值来接收,func()的返回值就是引用a,相当于a=2000,ret是a的别名,所以才有ret
	cout << ret << endl;
	cout << ret << endl;
	
	system("pause");
	return 0;

}

常量引用

1.形参定义时加上const,能够有效地防止误操作,防止形参改变实参。

#include<iostream>
using namespace std;

void prin( const int&ref) {
	//ref = 10;//这里就会提示错误,表示表达式是可修改的左值
	cout << "ref=  " << ref << endl;
}

int main() {
	
	int a = 50;
	prin(a);
	cout << "a=  " << a << endl;	
	system("pause");
	return 0;
}

2.如果直接在main函数定义,注意,在C++中,常量引用必须初始化,并且只能引用与其类型兼容的对象或字面值。因此,我们可以将常量引用绑定到一个字面值,如整数常量10,但不能将其绑定到一个非常量的对象,例如一个普通的整数变量。

//int &ref = 10;//非法提示:非常量引用的初值必须为左值,引用的必须是一块完整的内存空间。
const int &ref = 10;//这是正确的,相当于编译器把int temp=10;int  &ref=temp;这两步做了

总结

本文主要讲了引用的定义,通俗理解就是给变量起一个别名,定义一个指针常量指向原变量。要注意引用并不多不初始化或者一个引用指向多个变量。重点理解值传递、地址传递和引用作为函数参数。可以看出,当需要实参改变时,使用引用定义函数参数这种方式结构更加简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值