详谈C++引用&和指针在作为形参时的区别
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++){ b[i] = i; } }
如果在main函数中定义了一个int型的空指针并分别作为实参传入,如下:
int main(){ int *a = NULL; fun(a); for(int i=0; i<3; i++){ cout << a[i] << " "; } 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以确保在函数中该变量不会被修改。
以上这篇详谈C++引用&和指针在作为形参时的区别就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。
上一篇:C#中static void Main(string[] args) 参数示例详解
栏 目:C#教程
下一篇:WPF/Silverlight实现图片局部放大的方法分析
本文地址:https://www.xiuzhanwang.com/a1/C_jiaocheng/5835.html
您可能感兴趣的文章
- 01-10C++调用C#的DLL程序实现方法
- 01-10理解C#中参数的值和引用以及传递结构和类引用的区别
- 01-10浅谈C#中的值类型和引用类型
- 01-10C#调用Java方法实例详解
- 01-10关于finalize机制和引用、引用队列的用法详解
- 01-10C#调用C++DLL传递结构体数组的终极解决方案
- 01-10C# 泛型的约束
- 01-10详谈C# 图片与byte[]之间以及byte[]与string之间的转换
- 01-10浅析C# 中的类型系统(值类型和引用类型)
- 01-10C# 7.0之ref locals and returns(局部变量和引用返回)
阅读排行
本栏相关
- 01-10C#通过反射获取当前工程中所有窗体并
- 01-10关于ASP网页无法打开的解决方案
- 01-10WinForm限制窗体不能移到屏幕外的方法
- 01-10WinForm绘制圆角的方法
- 01-10C#实现txt定位指定行完整实例
- 01-10WinForm实现仿视频播放器左下角滚动新
- 01-10C#停止线程的方法
- 01-10C#实现清空回收站的方法
- 01-10C#通过重写Panel改变边框颜色与宽度的
- 01-10C#实现读取注册表监控当前操作系统已
随机阅读
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-10C#中split用法实例总结
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 01-10delphi制作wav文件的方法
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 01-10SublimeText编译C开发环境设置
- 04-02jquery与jsp,用jquery
- 01-11ajax实现页面的局部加载