原创 C++引用&和指针在作为形参时的区别

2011-1-9 21:00 7529 4 6 分类: 软件与OS

int n;

int &m = n;

在C++中,多了一个C语言没有的引用声明符&,如上,m就是n的引用,简单的说m就是n的别名,两者在内存中占同样的位置,不对m开辟新的内存空间,对m的任何操作,对n来说是一样的。

对于引用,有以下三条规则:

(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL 引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。

 

假如在一个函数中动态申请内存空间,用指针和用引用作形参会得到不同的结果,如下面的例子:

void fun(int* b){  //用指针做形参
 b = (int*)malloc(sizeof(int)*3);

 for(int i=0; i<3; i++){
  a = i;
 }
}

void fun(int* &b){  //用引用做形参
 b = (int*)malloc(sizeof(int)*3);

 for(int i=0; i<3; i++){
  b = i;
 }
}

如果在main函数中定义了一个int型的空指针并分别作为实参传入,如下:

int main(){
 int *a = NULL;

 fun(a);

 for(int i=0; i<3; i++){
  cout << a << " ";
 }
 cout << "\n";

 return 0;
}

结果用指针的函数会出现内存访问出错,用引用的函数则运行正常并正确输出1 2 3.

这是因为:

1.指针虽然是地址传递,但实际上也是在函数中又定义了一个新的指针让其与传入的指针指向同一地址。但两个指针本身作为变量在内存中的存放地址是不同的,就是说这是两个不同的变量,只是内容(即所指地址)相同。

2.在函数中对新定义的指针动态申请内存,但是当函数结束后,申请的内存的生命周期也就结束了,所以当回到主函数时,作为实参的指针地址和内容都没有变化。仍然是个空指针,对其进行访问自然出现了内存读错误了。

假如在main函数中这样写:

int *a = (int*)malloc(sizeof(int)*3);

就不会出现内存读错误了,但是输出结果还是错误的,道理也是一样的。

3.用引用作为实参传入时,fun函数中的b其实就是主函数中a的别名(或者叫外号),反正就是操作完全相同,地址相同,内容相同的一个变量,所以当fun函数返回时,对b的操作在主函数中对a同样有效。

 

再看一个例子:

int *a = NULL;

char* b = (char*)a;

 

int *a = NULL;

char* &b = (char*)a;

这一次是在编译阶段的区别:

用指针可以通过编译,而用引用则不可以,提示类型转换出错。

 

通过这两个例子可以看出,指针比引用灵活,也更加危险。

 

摘自『高质量c++编程』
条款一:指针与引用的区别
指针与引用看上去完全不同(指针用操作符’*’和’->’,引用使用操作符’.’),但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何决定在什么时候使用指针,在什么时候使用引用呢?
首先,要认识到在任何情况下都不能用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。

 

PS:引用在定义时不可加const,否则编译出错,在形参前面则可以加const以确保在函数中该变量不会被修改。

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户377235 2014-5-29 17:19

博主“2.在函数中对新定义的指针动态申请内存,但是当函数结束后,申请的内存的生命周期也就结束了,所以当回到主函数时,作为实参的指针地址和内容都没有变化。仍然是个空指针,对其进行访问自然出现了内存读错误了。”这段表述中有问题,函数结束之后,并非是申请内存的生命周期结束了,而是指向这块内存的指针生命周期结束,这块申请的内存没有关联的句柄,属于泄露内存。

用户1586988 2011-1-11 15:34

学习了
相关推荐阅读
用户894691 2011-01-12 19:43
冯诺依曼结构和哈佛结构的区别(转)
冯诺依曼架构: 把代码当作一种特殊的数据 来操作;指令总线和数据总线及其存储区域是统一的; 哈佛结构:指令总线和数据总线及其存储区域是分开的,独立的; 关于这个问题,有人说51地址线复用,就是冯诺...
用户894691 2011-01-12 19:21
软中断和硬中断的区别(转)
①硬中断是由外部事件引起的因此具有随机性和突发性;软中断是执行中断指令产生的,无面外部施加中断请求信号,因此中断的发生不是随机的而是由程序安排好的。②硬中断的中断响应周期,CPU需要发中断回合信号(N...
用户894691 2010-12-15 11:54
new和malloc的区别(转)
1、new 是c++中的操作符,malloc是c 中的一个函数2、new 不止是分配内存,而且会调用类的构造函数,同理delete会调用类的析构函数,而malloc则只分配内存,不会进行初始化类成员的...
用户894691 2010-11-26 20:20
some words
当你思维只对准一个对手的时候,你已经输了一半。你的思维整天围着它转,你的思维已经被限死,而且将对手踩下去就意味着自己站起来了吗?2010-10-14 吃亏是福。2010-11-21 “我们之所以会心累...
用户894691 2010-11-21 16:13
(转)c++中char * 和 char []的区别
c++中char * 和 char []的区别发布于:2010-3-17 10:19:15 已被阅读: 119 在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char ...
我要评论
2
4
关闭 站长推荐上一条 /3 下一条