C++中指针和引用的区别

来源:互联网 发布:js获取title属性 编辑:程序博客网 时间:2024/06/01 08:16

从概念上讲。指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。

而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。

C++中,指针和引用经常用于函数的参数传递,然而,指针传递参数和引用传递参数是有本质上的不同的:

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

而在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:

程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

最后,总结一下指针和引用的相同点和不同点:

★相同点:

●都是地址的概念;

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。

★不同点:

●指针是一个实体,而引用仅是个别名;

●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;

●引用没有const,指针有constconst的指针不可变;

●引用不能为空,指针可以为空;

●“sizeof引用”得到的是所指向的变量(对象)的大小,而“sizeof指针”得到的是指针本身的大小;

●指针和引用的自增(++)运算意义不一样;

●引用是类型安全的,而指针不是 (引用比指针多了类型检查

-------------------------------------------------------------------------------------------

指针和引用的区别总结

 

1.从现象上看:指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变

2.从内存分配上看:程序为指针变量分配内存区域,而引用不分配内存区域

3.从编译上看:程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变指向的对象(指针变量中的值可以改),而引用对象不能改。

 

引用与指针的区别: 

常常有人问引用与指针的区别,可能是指针和引用在功能上的相似,而是他们混淆这两个概念, 

现在总结以下二者的区别,希望大家能彻底弄清这两个概念根本性的差别: 

引用,一个变量的别名,为什么引入别名呢?原因是我们想定义一个变量,他共享另一个变量的 

内存空间,使用别名无疑是一个好的选择。变量是什么?是一个内存空间的名字,如果我们给这个 

内存空间在起另外一个名字,那就是能够共享这个内存了,引用(别名)的由此而来。 

指针,指向另一个内存空间的变量,我们可以通过它来索引另一个内存空间的内容,本身有自己的 

内存空间。 

二者区别:(1)引用访问一个变量是直接访问,而指针是间接访问。 

(2)引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间。 

(3)引用在开始的时候就绑定到了一个内存空间(开始必须赋初值),所以他只能是这个 

内存空间的名字,而不能改成其他的,当然可以改变这个内存空间的值. 

例如 

int i = 3,j = 4; 

int &x = i;//成为i的别名 

x = j;//不能否认x仍然引用i,并没有成为j的别名,只是修改了x和j共享的内存空间的值. 

这点与指针不同,指针在任何时刻都可以改变自己的指向

 

你无法让引用与其指示物分离。

 

和指针不同,一旦引用和对象绑定,它无法再被重新指向其他对象。引用本身不是一个对象(它没有标识; 当试图获得引用的地址时,你将的到它的指示物的地址;记住:引用就是它的指示物 )。

 

从某种意义上来说,引用类似 int* const p  这样的const指针(并非如 const int* p 这样的指向常量的指针)。不管有多么类似,请不要混淆引用和指针;它们完全不同。

 

 

 

 

[8.6] 何时该使用引用, 何时该使用指针?

尽可能使用引用,不得已时使用指针。

 

当你不需要“重新指向(reseating)”时,引用一般优先于指针被选用。这通常意味着引用用于类的公有接口时更有用。引用出现的典型场合是对象的表面,而指针用于对象内部。

 

上述的例外情况是函数的参数或返回值需要一个“临界”的引用时。这时通常最好返回/获取一个指针,并使用 NULL 指针来完成这个特殊的使命。(引用应该总是对象的别名,而不是被解除引用的 NULL 指针)。

 

注意:由于在调用者的代码处,无法提供清晰的的引用语义,所以传统的 程序员有时并不喜欢引用。然而,当有了一些 C++ 经验后,你会很快认识到这是信息隐藏的一种形式,它是有益的而不是有害的。就如同,程序员应该针对要解决的问题写代码,而不是机器本身。

 

---------------------------------------------------------------------------------------------

在C++中,既有引用又有取地址,好多人对引用和取地址不是很清楚,因此也无法区分。其实他们的区别可以用一句话概括:和类型在一起的是引用,和变量在一起的是取址。下面我们通过实例具体了解一下

1)引用在赋值=的左边,而取地址在赋值的右边,比如

  1. int a=3
  2. int &b=a;       //引用
  3. int *p=&a;       //取地址

2)和类型在一起的是引用,和变量在一起的是取址。 举例同样如上,还有下例:

  1. int function(int&i)
  2. {
  3. }  //引用

3)对于vector,上面2条同样适合

  1. vector<int> vec1(10,1)//initialize vec1: 10 elements, every element's value is 1
  2. vector<int>&vec2= vec1; // vec2 is  reference to vec1
  3. vector<int>*vec3= &vec2;//vec3 is addresss of vec1 and vec2