引用的学习与应用

本文详细介绍了C++中引用的特性,包括其作为函数参数的便捷性、与指针的区别、const引用的作用以及在数据传递中的优势。
摘要由CSDN通过智能技术生成

C++新增了一种复合类型--引用。引用时已定义的变量的别名。例如将data作为value的引用(别名),则可以随意使用data或value来表示该变量。

引用有何作用?

其主要作用时作为函数的形参(和函数的返回值)。这样函数的形参就是实参本身,而不是其副本。这样除指针外,引用也是为函数处理大型结构提供了一种非常方便的途径,同时对于设计类来说,引用也是必不可少的。

1.创建引用变量

类型名 & 引用变量名 = 被引用的变量名

int main()
{
	int a = 10;
	int& b = a;//b是a的引用
	cout << "a=" << a << ",b=" << b << endl;
	++a;
	cout << "a=" << a << ",b=" << b << endl;
	++b;
	cout << "a=" << a << ",b=" << b << endl;

	//将变量的地址输出
	cout << "&a=" << &a << ",&b=" << &b << endl;
	return 0;
}

程序执行如下: 

int a = 10;
cout<<&a<<endl;//&表示取地址
int &b = a;//&表示引用

 在定义语句(前面有数据类型)中&表示引用;

在使用语句(前面没有数据类型)中&表示取地址。

int main()
{
	int a = 10;
	int b = 20;
	int* p = &a;//&取地址符,a的前面没有类型
	int& b = a;//&引用,b的前面有类型
	int* q = p;//指针赋值
	int*& p1 = p;//&引用,p1是p的引用
	int** q2 = &p;//&取地址符,p的前面没有类型


	return 0;
}

其中 int*&p1 = p;  比较复杂,因为p的类型是int* ,所以它的引用应该是int * &。

创建指向a的引用和指针:

int a = 10;
itn &b = a;//引用,b是a的别名
int *p = &a;//指针,p保存a的地址

这样,表达式b和*p都可以表示a,而表达式&b和p都可以表示&a(即a的地址)。从这一点来说,引用看上去很像伪装的指针(其中,*解引用用算符被隐藏)。实际上,引用除了和指针不同外,还有其他区别。

指针和引用的区别:1.引用在定义时必须将其初始化,而指针可以先定义,再赋值。

int c = 10;
int &d;//错误,引用在定义时必须初始化
d = c;
int * p;//合法,定义指针不初始化
p =&c;//合法,给指针赋值

注意:引用在定义时必须进行初始化

指针和引用区别:2.引用更接近const指针,一旦与某个变量联系起来,就将一直效忠与它,不能再作为别的变量的引用。

也就是说:

int &b = a;

实际上和下述代码的效果类似:

int *const p = &a;

其中,引用b扮演的角色和*p相同。

下面的代码,试图将a变量的引用,改为b变量的引用,将会发生什么呢?

int main()
{
	int a = 10;
	int b = 20;
	int& c = a;//c是a的引用
	cout << "a=" << a << ",c=" << c << endl;//输出a,c的值
	cout << "&a=" << &a << ",&c" << &c << endl;//输出a,c的地址
	cout << endl;

	c = b;//试图将c修改为b的引用,c有没有引用b?
	cout << "b=" << b << ",c=" << c << endl;//输出b,c的值
	cout << "&b=" << &b << ",&c" << &c << endl;//输出b,c的地址
	cout << endl;

	c = 50;//修改引用的值
	cout << "a=" << a << ",b=" << b << ",c=" << c << endl;//输出a,b,c的值
	cout << "&a=" << &a << ",&b=" << &b << ",&c" << &c << endl;//输出a,b,c地址

	return 0;
}

2.将引用作为函数参数

引用经常被用作函数参数,使得函数中的形参为调用程序中实参的别名。这种传参数的方式称为按引用传递。C++新增这项特性是对C语言的超越,C语言只能按值传参或指针传递。按值传递导致形参使用的仅仅是实参的副本。

下面通过交换函数来进行演示:

//按值传递,形参只是实参的副本,不能达到交换值的效果
void Swapv(int x, int y)//错误的
{
	int tmp = x;
	x = y;
	y = tmp;
}
//按指针传递,可以实现两个数的交换
void Swapp(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
//按引用传值
void Swapr(int& x, int& y)
{
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 10, b = 20;//创建三组需要交换的变量
	int c = 10, d = 20;
	int e = 10, f = 20;
	cout << "按值传递,交换前" << a << "," << b << endl;
	Swapv(a, b);
	cout << "按值传递,交换后" << a << "," << b << endl;
	cout << endl;

	cout << "按指针传递,交换前" << c << "," << d << endl;
	Swapp(&c, &d);
	cout << "按指针传递,交换后" << c << "," << d << endl;
	cout << endl;

	cout << "按引用传递,交换前" << e << "," << f << endl;
	Swapr(e, f);
	cout << "按引用传递,交换后" << e << "," << f << endl;

	return 0;
}

数据传递示意图如下:

比较函数Swapr(按引用传递)和Swapp(按指针传递)。第一个区别是声明函数的方式不同:
 

void Swapr(int &x,int &y);
void Swapp(int *p1,int *p2);

另一个区别是指针版本需要在函数中全程使用*p1和*p2。而引用版本只需要使用x,y即可。

3.const引用

用const修饰的引用称为const引用,也成为常引用。

下面的程序用来计算x的立方,为了说明引用参数的特性,下面的代码会有一点奇怪。

//按值计算立方
int Cubev(int x)
{
	x = x * x * x;
	return x;
}
//按引用计算立方
int Cuber(int& x)
{
	x = x * x * x;
	return x;
}
int main()
{	
	int a = 2;
	int b = 3;
	int a3 = Cubev(a);
	int b3 = Cuber(b);
	cout << a << "的立方" << a3 << endl;
	cout << b << "的立方" << b3 << endl;

	return 0;
}

int Cuber(const int &x);

如果这样做,当编译器发现代码修改了x的值时,将生成错误信息。

注意:在引用传递中,由于形参就是实参的别名,对于形参的修改能直接反映到实参,如果这个函数不修改参数的值,则应该加上const。

普通的引用在使用时有一些注意事项,如下:

const引用不仅可以引用普通变量,还可以引用const变量,常量和表达式。如下:

const引用作为形参

如下面的实例,const引用作为形参,则实参的种类可以非常的丰富。

//按引用计算立方
int Cuber(const int& x)
{
	return x * x * x;
}

int main()
{
	int a = 2;
	int& b = a;
	long c = 5;
	int* p = &a;
	int arr[4] = { 1,2,3,4 };
	int a3 = Cuber(a);
	int b3 = Cuber(b);
	int c3 = Cuber(c);//产生临时变量
	int d3 = Cuber(*p);
	int e3 = Cuber(arr[2]);
	int f3 = Cuber(4);//产生临时变量
	int g3 = Cuber(a + 2);//产生临时变量
	cout << a << "的立方是" << a3 << endl;
	cout << b << "的立方是" << b3 << endl;
	cout << c << "的立方是" << c3 << endl;
	cout << *p << "的立方是" << d3 << endl;
	cout << arr[2] << "的立方是" << e3 << endl;
	cout << 4 << "的立方是" << f3 << endl;
	cout << a + 2 << "的立方是" << g3 << endl;
	return 0;
}

应尽可能的使用const

将引用参数声明为const的理由有三个:

使用const可以避免无意中修改数据。

使用const能够处理const和非const实参,否则只能接受非const实参。

使用const引用使函数能够使用临时变量。

4.指针与引用有什么区别?

1.从语法规则上讲,指针变量储存某个实例(变量或对象)的地址;引用时某个实例的别名。

2.程序为指针变量分配内存;而不为引用分配内存。

3.指针变量的值可以发生变化,储存不同实例的地址;引用在定义时就被初始化,之后无法改变(不能是其它对象的引用)。

4.指针变量的值可以为空(NULL,nullptr),但引用不能为空,没有空引用。

5.指针变量作为形参时需要测试它的合法性(判空NULL);引用不需要判空(引用不能为NULL)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值