C++ 学习之旅(8)——一文搞懂指针、引用、函数参数的传值调用、指针调用和引用调用
廢話少說,直接上代碼:
#include <iostream>int main() {int a = 5;int* ptr = &a;int& ref = a;std::cin.get(); //設置斷點 }為了避免混淆,我建議在定義指針時寫int* ptr而不是int *ptr,同理,定義引用寫成int& ref而不是int &ref。
設置斷點,然后Debug程序,看看源程序的匯編程序是什么:
 
 
 精彩的地方來了,指針和引用實際上干的是同樣的事,都是把變量a所在的偏移地址傳給ptr指針,只不過指針的標號名為ptr,引用的標號名為ref而已。
再看看賦值操作:
#include <iostream>int main() {int a = 5;int* ptr = &a;int& ref = a;*ptr = 6; //賦值ref = 7; //賦值std::cin.get(); }
 在匯編語言中還是一樣的!
最后看一下函數參數傳遞的三種方式:
#include <iostream>void Increment1(int value) //傳值 {value++; }void Increment2(int* value) //指針 {(*value)++; }void Increment3(int& value) //引用 {value++; }int main() {int a = 5;Increment1(a);Increment2(&a);Increment3(a);std::cin.get(); }Increment1函數
 Increment2函數
Increment3函數
 可以看到指針和引用還是一樣的,結合調用的代碼看:
 首先,把5送到內存地址為a的雙字大小的空間中;
 對于Increment1,從內存地址為a的雙字大小的空間中取出內容(整數5),送到eax寄存器中,然后call函數Increment1,把eax加一,最后送到內存地址為value的空間中,而不是內存地址為a的空間,如圖:
 
 對于Increment2,取內存地址為a的偏移地址,送到eax寄存器中,然后call函數Increment2,如圖:
 
 先是尋址參數value,從中取出偏移地址送到eax,再用eax尋址,找到數值5送到ecx,然后ecx加一,再將結果ecx送回到偏移地址為value空間中記錄的那個地址,即內存地址a,這樣就實現了對a的加一操作。
 
 順便看下此時的value空間,記錄的是內存地址a的偏移地址:
 也就是說,如果使用傳值調用,內存地址為參數value的空間中記錄的就是數值,運算的結果也會記錄在這里,但是如果函數退出,這一塊空間就會清除,所以結果并沒有保存。如果使用指針和引用調用,內存地址為參數value的空間中記錄的就是偏移地址,然后根據這個偏移地址取值,作運算,結果也是根據這個偏移地址送回去,而這塊空間即使函數退出也不會消失。
總結
以上是生活随笔為你收集整理的C++ 学习之旅(8)——一文搞懂指针、引用、函数参数的传值调用、指针调用和引用调用的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 九州风神推出墨菲斯机箱,售价 1399
- 下一篇: 奥特曼为重返OpenAI做让步,没加入董
