1. 程式人生 > 其它 >引用:&(reference)與間接引用:*(dereference)

引用:&(reference)與間接引用:*(dereference)

技術標籤:Android安卓系統開發

1. 符號&(reference),表示".....的地址"("address of"),因此稱為地址操作符(adress operator),又稱引用操作符(reference operator)。例如:

foo = &myvar;

將變數myvar的地址賦給變數foo,因為當在變數名稱myvar 前面加ampersand (&) 符號,foo指的將不再是該變數的內容,而是它在記憶體中的地址。在程式執行之前,變數的記憶體地址是不可知的,但為了便於理解,我們假設myvar的記憶體地址是1776。然後我們看下列程式碼:

myvar = 25;

foo = &myvar;

bar = myvar;

各自變數的儲存值如下圖所示:


儲存其它變數地址的變數(如上面例子中的foo ),我們稱之為指標(pointer)。在C++ 中,指標pointers 有其特定的優點,因此經常被使用。在後面我們將會看到這種變數如何被宣告。

2. 符號*(dereference),表示".....所指向的值"("value pointed to by"),看下面的宣告:

baz = *foo;

可以讀作:baz等於foo所指向的值。baz的值變為25,因為foo儲存的是記憶體地址1776,而*foo

指的是記憶體地址1776指向的值,即25。


注意加或不加星號*的不同(下面程式碼中註釋顯示瞭如何讀這兩個不同的表示式):

beth = ted;// beth 等於 ted ( 1776 )

beth = *ted;// beth 等於 ted 所指向的數值 ( 25 )

3. 引用在函式中的使用

複製程式碼

#include <iostream>
using namespace std;

int addition (int a, int b)
{
  int r;
  r=a+b;
  return r;
}

int main ()
{
  int x=5, y=3, z;
  z = addition (x,y); 
  cout << "The result is " << z;//The result is 8
}

複製程式碼

上面的函式 addition 有兩個引數int a 和 int b,這兩個引數都是通過值(by value)傳遞的。它的意思是,當呼叫函式 addition(x, y)的時候,x 和 y 的值(5 和 3)會被 copy 一份,然後分別賦值給 a 和 b。在函式內部修改 a 和 b 的值,並不會對外部的 x 和 y 造成影響。

但有時候,需要在函式內部修改外部的變數,怎麼辦呢?為了實現這個需求,可以通過引用(by reference)傳參。看下面的例子

複製程式碼

// passing parameters by reference
#include <iostream>
using namespace std;

void duplicate (int& a, int& b, int& c)
{
  a*=2;
  b*=2;
  c*=2;
}

int main ()
{
  int x=1, y=3, z=7;
  duplicate (x, y, z);
  cout << "x=" << x << ", y=" << y << ", z=" << z; //x=2, y=6, z=14
  return 0;
}

複製程式碼

通過在引數型別後面新增符號 &,函式 duplicate 的三個引數都宣告成了引用。當變數 x ,y,z 以引用的方式傳入函式 duplicate 時,實際傳入的不再是變數的值的拷貝,而是變數自己。由此,在函式內部,修改 a, b, c 的值,也就是修改了外部 x ,y,z 的值。

4. 效能問題和常數引用

對於引數是通過值(by value)傳遞的函式,引數的值會被 copy 一份傳入函式。對於基本型別比如 int,這樣的開銷是很小的。但對於大的複合型別,不如 string,這樣的開銷還是很大的。比如:

string concatenate (string a, string b)
{
  return a+b;
}

如果有兩個很長的字元作為 concatenate 的引數,那麼意味著,僅僅是在呼叫這個函式的時候,就會有大量的資料被拷貝。

但是,如果我們使用引用,這樣的問題就可以被避免:

string concatenate (string& a, string& b)
{
  return a+b;
}

- 注意這種通引用 by reference 傳遞引數的方式只是在C++中適用。在C 語言中,我們必須用指標(pointers)來做相同的操作。

綜上可知,使用引用傳遞引數有兩個優勢:

1. 不需要再 copy 值,提升效能。

2. 修改了引數的值也就修改了外部變數的值。

如果只想利用第1點,避免第2點,怎麼辦?方法是把引數宣告為常量(constant):

string concatenate (const string& a, const string& b)
{
  return a+b;
}

這樣,使用常量引用,既達到了像值傳遞那樣使用引數,又可以像引用傳遞那樣提升效能。