再谈引用和指针

引用可以实现指针的功能,而且更加方面,那么,为什么还要指针呢?这是因为指针可以为空,但引用不能为空,指针可以被赋值,但是引用只能被初始化,不可以被赋为另一对象的别名,如果你想一个变量记录不同对象的地址,那么这时就必须使用指针。具体可以看下面的例子:

#include <iostream>
using namespace std;
int main()
{
	int a = 1 ;
	int *p ;
	p = &a ;   //存放变量a的地址
	int b = 2 ;
	p = &b ;  //存放变量b的地址
	return 0 ;
}


我们可以看到指针p一开始存放了变量a的地址,后面有存放了变量b的地址。既可以存放不同变量的地址。

#include <iostream>
using namespace std;
int main()
{
	int a = 1 ;
	int &p = a ;
	int b = 2 ;
	&p = b ;   //错误:不能将p作为变量b的别名
	return 0 ;
}


由于引用只能被初始化,不能被赋值,所以我们不能讲p作为变量b的别名。

另外一点,在堆中创建的一块内存区域,必须要用指针来指向它,否则该区域将会变成无法访问的内存区域。当然我们也可以使用引用来引用指向内存区域的指针。请看下面的例子:

#include <iostream>
using namespace std;
int main()
{
	int *p = new int ;
	int &rp = *p ; //rp作为p指向的地址处的值的别名
	rp = 4 ;  //我们可以通过别名rp来修改p指向的地址处的值
	cout << "ra:\t" << rp << endl ;
	cout << "*p:\t" << *p << endl ;
	return 0 ;
}

 

但是我们要明白一点:我们不可以直接使用引用来指向堆中新建的空间,因为引用只是一个别名,不能当做指针来使用。例如:

#include <iostream>
using namespace std;
int main()
{
	int &p = new int ;
	return 0 ;
}

但是如果我们作如下修改,则可以:

#include <iostream>
using namespace std;
int main()
{
	int *&rp = new int ;
	return 0 ;
}


即在&rp前面加了“*”,该语句的意思是:我们在堆中新建了一个空间,返回了该空间的地址,该地址有一个指针来保存。而该指针又定义了一个别名rp。这样rp可以看做是一个指针,可以像操作指针那样操作rp。

#include <iostream>
using namespace std;
int main()
{
	int *&rp = new int ;
	*rp = 2 ;
	cout << "*rp:\t" << *rp << endl ;
	return 0 ;
}


我们可以看到结果输出了2。

但是一般情况下,我们不会这样使用引用。我直接写上指针名即可,因为这样使用引用用一定的危险:因为在机器运行不正常的情况下,就是当在机器虚拟内存太小时,无法创建新空间的情况下,new int 会返回一个空指针,我们知道引用不能为空,因此这种情况下使用该语句:int *&rp = new int ;就会导致一个没有用的别名,而使(*)读取一个无用的别名将导致系统崩溃。解决的办法是:不要将引用初始化为新建内存区域的别名,而要将rp初始化为指向该区域指针的别名,前提是首先判断该指针不为空。

#include <iostream>
using namespace std;
int main()
{
	int *&p = new int ;
	if (p != NULL)
	{
		int &rp = *p ;//一般是p指向的数据的别名
		rp = 2 ;
		cout << "rp:\t" << rp << endl ;
	}
	return 0 ;
}


 

下面再具体总结下引用和指针的区别:

1、指针可以为空,引用不能为空

2、指针可以被赋值,引用不能被赋值

3、指针可以指向堆中的空间,引用不能指向堆中的空间

这样,我们就可以有选择的使用指针和引用了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值