重點小整理,給自己提起記憶用的
懶人包整理法
種類 | 呼叫時使用 | 程式碼寫法 |
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 reference | swap(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=28FF38 | iPointer自己的記憶體起始位置在哪 |
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寫成下面的樣子:
則呼叫 swap(x, y) 後,x和y的值並不會有變化。void swap(int a, int b){ int tmp = a; a = b; b = tmp; }
- call by address (或call by pointer)
利用指標來做參數傳遞,這種方法骨子裡仍是call by value,只不過call by value的value,其資料型態為指標罷了。我們同樣看看用call by address來寫swap交換兩個integer的例子。
呼叫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。void swap(int* a, int* b){ int tmp = *a; *a = *b; *b = tmp; }
- call by reference
這是C++才加進來的東西,C本身並沒有call by reference。call by reference基本上是把參數做個別名 (alias),以下面的swap為例:
使用時,只要呼叫swap(x, y),就可以讓x和y的值交換。在這個例子中,a 就是 x, b 就是 y。swap(int &a, int &b){ int tmp = a; a = b; b = tmp; }
------------------------------------------------------------------------------------------------------------
參考:
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 value、call by reference 與 call by pointer
http://vr.me.ncku.edu.tw/xms/content/show.php?id=456
沒有留言:
張貼留言
如果久久沒有反應,請直接寄信
應該是我不太會用google blogger 導致有留言過久未處理><
實在深感抱歉..