本文来源于
http://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in?rq=1
我用自己的语言表述一下:
总的区别:
1,指针可以多次改变其值,而引用一旦确定就不能改变关系。
就是说指针可以更改其指向的元素,而引用是绑定的关系
2,指针可以指向不存在的地方,其值可以为NULL,而引用必须和一个具体的元素绑定。
3,指针可以有算术运算,比如p++;但引用是不可以的
具体的内在区别:
c++标准非常小心的避开了规定编译器应该如何实现引用,大多数编译器将其通过指针来实现。
比如是下面这样的声明:
int &ri=i;
如果没有被优化掉(if it's not optimized away entirely,翻译的可能不准确),那么分配和指针同样大小的内存,然后把指针放到内存里面
综合来说,使用的时候注意一下两点就好:
- 在函数的参数里面和返回量使用引用
- 用指针来实现结构体和算法
As a general rule,
Use references in function parameters and return types to define useful and self-documenting interfaces.
Use pointers to implement algorithms and data structures.
补充一点我遇到的情况:
void foo(int a)
{
a++;
}
int main()
{
int a = 1;
foo(a);
std::cout << a;
}
这个函数执行之后a的值是不会改变的!
原因出于C语言固有的函数策略。具体地说:当我们以变量a为函数foo的参数的时候,函数foo将变量a的数据值刷写到该函数治下的变量x,也就是说,函数foo内部的变量x只是拥有了作为调用该函数的参数即变量a的数据值的私有副本。换句话说,函数foo内部的变量x,只是被初始化了一个值,至于这个值是从哪里来的,站在变量x的角度,它自己是永远无法知道的。这犹如: 代码: x = a ; 作为左值的x,只是被赋值以另一个左值a所能handle的内存区域上的数据,除此之外,有关左值a自己的其他一切信息,都不会传达给x。所以,在执行了上述语句之后,分别对左值x和a的任何更改性操作,都不会影响到对方。
要想通过改变a的值,就需要使用引用和指针了:
void foo(int &a)
{
a++;
}
或者:
void bar(int *x)
{
(*x)++;
}
我们调用函数bar的写法,也应当有所改变,应当这样:
bar(&a);
此时,被传入函数bar的参数,是一个指向变量a的指针。函数bar治下的变量x(这是一个指针变量)所拥有的,依然仅仅是前者的值的一个私有副本。 函数bar在其内部,通过把间接访问(星号)操作符作用在这个私有副本上,handle到了变量a所对应的那块内存区域,从而,间接地在那块区域上刷写了新的数据。当然,变量a自已对此是一无所知的,只不过,以后当其他地方又“召唤”a的时候,a若自有记性,会心说:“唉?这个值跟原来的不一样了嘛,一定是哪个臭小子,在背地里拿了一个指向我的指针去间接地修改了这个值……”