从内存角度理解函数值传递与地址传递的区别

**
新人博客小编一枚,希望与大家多多交流C++的学习心得,欢迎大家批评指教、共同进步!

对C++初学者来说,对于值传递和地址传递的使用都停留在“用而不懂”的状态,以至于在实际应用经常会发生各种错误,今天我从内存的角度分析一下,希望帮助初学者从根本来理解两者之间的区别,这样才能在学习C++的道路上取得更大地提升。

一、基本概念

形参:函数定义中的参数;
实参:实际传入函数中的参数;
值传递:以变量、常量等为函数参数,将实参的值复制一份到函数的形参中,函数中参数的修改对实参不会产生影响;
地址传递:以指针为函数参数,传入的实参为地址,形式参数接收地址,函数中参数的修改的同时也修改了实参。

以经典的swap函数作为案例来研讨一下值传递和地址传递的区别。

二、值传递

#include
using namespace std; //swap函数定义
void swap(int num1, int num2)  //形参num1,num2
{int temp = num1;num1 = num2;num2 = temp;cout << "调用swap函数中:" << "num1=" << num1 << "  num2=" << num2 << endl;
}int main()
{int a = 50;int b = 100;cout << "调用swap函数前:" << "a=" << a << "  b=" << b << endl;swap(a, b);   //调用swap函数,a、b为传入的实参cout << "调用swap函数后:" << "a=" << a << "  b=" << b << endl;system("pause");return 0;
}

运行结果:
在这里插入图片描述
可以看出调用swap函数后,并没有改变a和b的值。程序运行过程中,假定在栈区开辟一块内存空间,存储局部变量和函数参数==(注:实际程序运行过程中,函数参数不大于6个都由寄存器存放)==,内存空间变化如下图所示:
在这里插入图片描述
由图可知,程序执行到swap函数前时,栈区存放了a、b两个变量;在调用swap函数过程中,栈区增加了num1、num2、temp三个变量,并实现了num1、num2值的交换;swap函数调用完成后,num1、num2、temp三个变量所占内存会被系统自动释放,只剩下a、b两个变量。很明显,a和b的值自始至终都没有实现交换,所以并不会改变。

三、地址传递

#include
using namespace std; //swap函数定义
void swap(int *num1, int *num2)  //形参num1,num2
{int temp = *num1;*num1 = *num2;*num2 = temp;cout << "调用swap函数中:" << "num1=" << *num1 << "  num2=" << *num2 << endl;
}int main()
{int a = 50;int b = 100;cout << "调用swap函数前:" << "a=" << a << "  b=" << b << endl;swap(&a, &b);   //调用swap函数,a、b为传入的实参cout << "调用swap函数后:" << "a=" << a << "  b=" << b << endl;system("pause");return 0;
}

运行结果:
在这里插入图片描述
从运行结果可以发现,与值传递不同,通过地址传递的方式,实现了a和b的交换。接下来,我们一起看一下其实现的原理,见下图:
在这里插入图片描述
由图可知,swap函数调用时,指针num1指向a的地址,指针num2指向b的地址,即 int* num1=&a,int* num2=&b,所以swap函数执行的*num1和 *num2值交换实际上是变量a和b的值交换。在swap函数调用完成后,指针num1、num2的地址空间就被系统释放,a和b的值也发生了交换。

四、总结

若形参发生改变,值传递并不会对实参产生任何改变,而地址传递的实参会发生相应改变。
初学者对值传递和地址传递的使用极易产生混淆并不理解其原理,相信读完这篇文章后,能区分值传递和地址传递的使用情况,并对指针的应用有了更直观的理解。
如有错误,欢迎指出!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部