int*&、int&*

致謝作者;原文出處:http://tech.ddvip.com/2012-10/1349927012183265.html


信很多CPPers跟我一樣,曾經在指針和引用裏徘徊了很久很久。經常弄混指針和引用,尤其是見到如題中列出那些用法,着實是傷腦經。

後來,在項目中用着用着,就能搞清楚區別了,算是會用吧。然而,對於一個Programmer,最忌諱的就是不知其所以然,會用和懂是兩番天地。停留在會用的人,始終是原地打轉;而懂的人,一通百通,能舉一反三。

本文,就如題的指針和引用的用法做一個介紹。

首先我們來普及一下概念,說明一下什麼是指針和引用,這裏借用一下變量名作爲過渡。

     ■指針 ---- 指向某一塊內存的變量,其本身存儲的信息就是內存地址的首地址,其類型決定指向內存的大小。
            比喻,超市的儲物櫃。我記住我放包的櫃子在第一排右起第三個,這裏的1-3就是一個地址,通過地址,我可以找到櫃子。這裏的地址就是一個指針。

     ■變量 ---- 某一塊內存地址數據值的名字
            比喻,超市的儲物櫃。我記住我放包的櫃子上有一張貼紙,上面寫着18,通過18,我可以找到櫃子。這裏的18,就是變量名了。

     ■引用 ---- 變量的別名
            比喻,超市的儲物櫃。櫃子的貼紙上面寫着18,但是18不好記,我用諧音記憶法,把18想成“要發”,通過“要發”,也可以找到櫃子。這裏“要發”就是一個引用。

通過上面的比喻可以看出來,要找到櫃子,有三種方法:

1. 第一排右起第三個                      地址(指針)
2. 櫃子貼紙上號爲18的                    變量名
3. “要發”                              引用

理解了指針、引用的概念,我們來看看它們的使用吧,這裏以經典的值交換爲例,來說明int、int*、int&、int*&、int&*、int**。

1. int

#include <iostream>    
 using namespace std;    
          
 void swap1(int a, int b){    
     int tmp;    
     tmp = a;    
     a = b;    
     b = tmp;    
 }    
 int main(){    
     int a = 1;    
     int b = 2;    
     swap1(a, b);    
     cout<<"a = "<<a<<endl;    
     cout<<"b = "<<b<<endl;    
     system("pause");    
     return 0;    
 }

交換失敗。基礎牢靠的同學一眼就看出來,這樣的交換隻是交換了形參的值,是無法達到交換值的效果的,這段程序很簡單,不做細說。

2. int*

#include <iostream>    
using namespace std;    
         
void swap2(int *a, int *b){    
    int tmp;    
    tmp = *a;    
    *a = *b;    
    *b = tmp;    
}    
         
int main(){    
    int a = 1;    
    int b = 2;    
    swap2(&a, &b);    
    cout<<"a = "<<a<<endl;    
    cout<<"b = "<<b<<endl;    
    system("pause");    
    return 0;    
}

交換成功。上面是的swap2接受的參數是地址,我們傳入地址,就可以直接操作實參的值了,這個也很簡單,不做細說。

3. int&

#include <iostream>    
using namespace std;    
         
void swap3(int& a, int& b){    
    int tmp;    
    tmp = a;    
    a = b;    
    b = tmp;    
}    
         
int main(){    
    int a = 1;    
    int b = 2;    
    swap3(a, b);        
        cout<<"a = "<<a<<endl;    
    cout<<"b = "<<b<<endl;    
    system("pause");    
    return 0;    
}

交換成功。引用即別名,通過引用也是可以直接訪問到實參和控制實參的,這裏不做細說。

4. int*&

#include <iostream>    
 using namespace std;    
          
 void swap5(int *&a, int *&b){    
     int tem = *a;    
     *a = *b;    
     *b = tem;    
 }    
          
 int main(){    
     int a = 1;    
     int b = 2;    
          
     int *aPtr = &a;    
     int *bPtr = &b;    
     int *&arPtr = aPtr;    
     int *&brPtr = bPtr;    
          
     swap5(arPtr, brPtr);    
          
     cout<<"a = "<<a<<endl;    
     cout<<"b = "<<b<<endl;    
     system("pause");    
     return 0;    
 }

交換成功。這個稍微複雜一點,int*&  value這樣一個聲明,我們從最接近value的符號看起,是個&,說明value是一個引用,它是一個什麼引用呢?再看*,它是一個指針的引用,即指針的別名,我們用*value就可以訪問到實參的值了。所以,其交換函數的內部邏輯跟int *是一樣的。

5. int &*

交換成功。這樣定義就不合法,如果從字面上來看,我們分析一下,如int &* value,最接近value的是*,說明value是一個指針,再看前面的是&,說明是一個指針的引用,而指針是無法被引用的,所以,這樣的定義是不合法的,不要記這個。(zhhz的理解是:指針是無法被引用的,因爲指針加減改變了自己,也就不是原來的那個指針了,這樣就產生了矛盾)

6. int**

#include <iostream>    
 using namespace std;    
          
 void swap6(int **a, int **b){    
     int tmp;    
     tmp = **a;    
     **a = **b;    
     **b = tmp;    
 }    
          
 int main(){    
     int a = 1;    
     int b = 2;    
     int *aPtr = &a;//指向數據的指針    
     int *bPtr = &b;//指向數據的指針    
     int **aaPtr = &aPtr;//指向指針的地址的指針    
     int **bbPtr = &bPtr;//指向指針的地址的指針    
     swap4(aaPtr, bbPtr);    
     cout<<"a = "<<a<<endl;    
     cout<<"b = "<<b<<endl;    
     system("pause");    
     return 0;    
 }

交換成功。同樣的,比如int **value, 最接近value的是*,說明value是一個指針,在前一個是*,說明是一個指向指針的指針,這樣是合法的,那麼如何訪問value代表的實際參數的值呢?很簡單,用**value就可以了,記住*是一個操作符,如同&一樣,不過&是取地址操作符,而*是取值操作符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章