本文來源于
http://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in?rq=1
我用自己的語言表述一下:
總的區(qū)別:
1,指針可以多次改變其值吃沪,而引用一旦確定就不能改變關系。
就是說指針可以更改其指向的元素,而引用是綁定的關系
2穆咐,指針可以指向不存在的地方拓售,其值可以為NULL签孔,而引用必須和一個具體的元素綁定。
3捶障,指針可以有算術運算,比如p++纲刀;但引用是不可以的
具體的內(nèi)在區(qū)別:
c++標準非常小心的避開了規(guī)定編譯器應該如何實現(xiàn)引用项炼,大多數(shù)編譯器將其通過指針來實現(xiàn)。
比如是下面這樣的聲明:
int &ri=i;
如果沒有被優(yōu)化掉(if it's not optimized away entirely示绊,翻譯的可能不準確)锭部,那么分配和指針同樣大小的內(nèi)存,然后把指針放到內(nèi)存里面
綜合來說面褐,使用的時候注意一下兩點就好:
- 在函數(shù)的參數(shù)里面和返回量使用引用
- 用指針來實現(xiàn)結構體和算法
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;
}
這個函數(shù)執(zhí)行之后a的值是不會改變的拌禾!
原因出于C語言固有的函數(shù)策略。具體地說:當我們以變量a為函數(shù)foo的參數(shù)的時候展哭,函數(shù)foo將變量a的數(shù)據(jù)值刷寫到該函數(shù)治下的變量x湃窍,也就是說,函數(shù)foo內(nèi)部的變量x只是擁有了作為調(diào)用該函數(shù)的參數(shù)即變量a的數(shù)據(jù)值的私有副本摄杂。換句話說坝咐,函數(shù)foo內(nèi)部的變量x,只是被初始化了一個值析恢,至于這個值是從哪里來的墨坚,站在變量x的角度,它自己是永遠無法知道的映挂。這猶如: 代碼: x = a ; 作為左值的x泽篮,只是被賦值以另一個左值a所能handle的內(nèi)存區(qū)域上的數(shù)據(jù),除此之外柑船,有關左值a自己的其他一切信息帽撑,都不會傳達給x。所以鞍时,在執(zhí)行了上述語句之后亏拉,分別對左值x和a的任何更改性操作扣蜻,都不會影響到對方。
要想通過改變a的值及塘,就需要使用引用和指針了:
void foo(int &a)
{
a++;
}
或者:
void bar(int *x)
{
(*x)++;
}
我們調(diào)用函數(shù)bar的寫法莽使,也應當有所改變,應當這樣:
bar(&a);
此時笙僚,被傳入函數(shù)bar的參數(shù)芳肌,是一個指向變量a的指針。函數(shù)bar治下的變量x(這是一個指針變量)所擁有的肋层,依然僅僅是前者的值的一個私有副本亿笤。 函數(shù)bar在其內(nèi)部,通過把間接訪問(星號)操作符作用在這個私有副本上栋猖,handle到了變量a所對應的那塊內(nèi)存區(qū)域净薛,從而,間接地在那塊區(qū)域上刷寫了新的數(shù)據(jù)蒲拉。當然罕拂,變量a自已對此是一無所知的,只不過全陨,以后當其他地方又“召喚”a的時候爆班,a若自有記性,會心說:“唉辱姨?這個值跟原來的不一樣了嘛柿菩,一定是哪個臭小子,在背地里拿了一個指向我的指針去間接地修改了這個值……”