2012年5月1日 星期二

【程式語言】C/C++之指標 (pointer)And參考 (reference)

C/C++之指標 (pointer),參考 (reference) 
重點小整理,給自己提起記憶用的



懶人包整理法
種類    呼叫時使用                    程式碼寫法                                                             
Call by Value            swap(x, y)
x,y值改變
  
void swap(int a, int b){
    int tmp = a;
    a = b;
    b = tmp;
  } 
call by address
(指標的運用)
swap(&x, &y)
x,y值改變
&x,&y沒改變
  
void swap(int* a, int* b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
  }
call by referenceswap(x, y)
x,y值改變
  
swap(int &a, int &b){
    int tmp = a;
    a = b;
    b = tmp;
  }





1.call by value,
2.call by  address,
3.reference


指標 (pointer):
int *p1 = &a;
p1變數所記載的值是變數a的記憶體 (memory) 位址
&,稱為address of (取址)
每宣告一個pointer時,就會配置一塊4 bytes的記憶體空間,
所以當
假設a的記憶體位置在x0(16進位)005
*p1指向x0005
當a進一位x0006
*p1指向x0006
a+=1
*p1=6
a=6
如果是
*p1進一位x0006
a還是在x0005
*p1+=1
*p1=6
a=5




void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}
a和b為x與y的別名,即:a就是x,b就是y,a和b不是x和y的複製品

int iValue = 10;
int *iPointer = &iValue;
 
printf("iPointer的value=%d \r\n"            ,  *iPointer);      //取值要用* 
printf("iPointer儲存value的address=%X \r\n" ,  iPointer);       //沒有*就是印出本身儲存的記憶體位置   
printf("iPointer本身的address=%X \r\n"      ,  &iPointer);      //取得記憶體位置都是用& 
printf("iValue  本身的address=%X \r\n"      ,  &iValue);        //取得記憶體位置都是用& 
printf("iPointer的size=%d \r\n"             ,  sizeof(iPointer));  
printf("iValue的size=%d \r\n"               ,  sizeof(iValue));  



下面為執行結果以及說明,:
output   說明
   iPointer的value=10印出儲存的記憶體位置本身的value,前面說過pointer是用來儲存記憶體位置,
如果要取得該記憶體位置的value,就是利用*
   iPointer儲存value的address=28FF3C印出iPointer儲存的資訊(記憶體位置)
   iPointer本身的address=28FF38iPointer自己的記憶體起始位置在哪
   iValue  本身的address=28FF3C第四行就是印出iValue本身的記憶體起始位置,會發現跟第二行一樣,因為iPointer就是儲存這個資訊
   iPointer的size=4印出iPointer的大小,前面說過,每個pointer的大小都為4 bytes,不論型態為和
   iValue的size=4印出iValue本身的大小,因為是interger,所以為4 bytes





  • call by value
    假設函式A呼叫函式B(p, q),則B中的p和q是「複製」自函式A所傳入的參數,B中對p, q所做的任何運算都不會影響到A中的p和q,因為B執行完後,並不會把複製的p, q存回到A中。這種參數傳遞方式,我們稱之為call by value。
    以swap這個常見的函式為例,若swap寫成下面的樣子:
    
      void swap(int a, int b){
        int tmp = a;
        a = b;
        b = tmp;
      }
    
    則呼叫   swap(x, y)   後,x和y的值並不會有變化

  • call by address (或call by pointer)
    利用指標來做參數傳遞,這種方法骨子裡仍是call by value,只不過call by value的value,其資料型態為指標罷了。我們同樣看看用call by address來寫swap交換兩個integer的例子。
    
      void swap(int* a, int* b){
        int tmp = *a;
        *a = *b;
        *b = tmp;
      }
    
    呼叫swap時,要寫成swap(&x, &y)。呼叫swap時,x的指標 (x的儲存位置) 與y的指標 (y的儲存位置) 會被複製一份到swap中,然後把該位置內所記載的值做更換。swap結束後,&x (address of x) 和&y (address of y) 依然沒變,只是address of x所記錄之變數值與address of y所記錄之變數值交換了。因為&x 和&y 其實是利用call by value在傳,因此,call by address其實骨子裡就是call by value。

  • call by reference
    這是C++才加進來的東西,C本身並沒有call by reference。call by reference基本上是把參數做個別名 (alias),以下面的swap為例:
    
      swap(int &a, int &b){
        int tmp = a;
        a = b;
        b = tmp;
      }
    
    使用時,只要呼叫swap(x, y),就可以讓x和y的值交換。在這個例子中,a 就是 x, b 就是 y。

------------------------------------------------------------------------------------------------------------
參考:
1.最先Google到..
http://kpxx.blogspot.com/2009/01/cc-pointer-reference.html
2.與上面作者同一人
http://sandwichc-life.blogspot.com/2007/10/cc-pointer-reference.html
3.有程式解說,比較易懂
http://blog.kenyang.net/2011/11/c-pointer.html
4.call by valuecall by reference  call by pointer 
http://vr.me.ncku.edu.tw/xms/content/show.php?id=456

沒有留言:

張貼留言

如果久久沒有反應,請直接寄信
應該是我不太會用google blogger 導致有留言過久未處理><
實在深感抱歉..