700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C++ 学习之旅(8)——一文搞懂指针 引用 函数参数的传值调用 指针调用和引用调用

C++ 学习之旅(8)——一文搞懂指针 引用 函数参数的传值调用 指针调用和引用调用

时间:2023-05-21 17:44:35

相关推荐

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的空间中记录的就是偏移地址,然后根据这个偏移地址取值,作运算,结果也是根据这个偏移地址送回去,而这块空间即使函数退出也不会消失。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。