参数传递之“值传递和址传递的统一理解”(c++版)

一,案例

#include<iostream>
using namespace std;
void GetMemory(int *ptr, int size)
{
    ptr = new int[size];
}

int main()
{
    int *ptr = NULL;
	cout<<"第一处,ptr="<<ptr<<endl;

    GetMemory(ptr, 100);

    cout<<"第二处,ptr="<<ptr<<endl;
    delete[] ptr;
	return 0;
}

简介:上述案例中,试图在自定义函数中为全局数组分配内存,但是失败了。

二,分析

在c++语言(c语言也是)当中,函数传参数时,都是为实参创建一个副本(也就是形参),然后拿着这个副本代替实参 在函数内部进行操作。

当代码运行到主函数的第一句的时候,指针变量ptr指向了NULL。

当上述代码运行到主函数的第三句时,也即:GetMemory(ptr, 100);

此时,实参是ptr。函数会生成一个ptr的副本代替ptr进入GetMemory函数中进行操作。这个副本和ptr的关联之处在于,它们的值是相同的。也就是说它们指向同一块内存。(但是它们的地址不相同)在GetMemory函数里面,上述代码给ptr的副本重新分配内存,也即:让ptr的副本指向另一块内存。执行完之后,ptr和ptr的副本指向的内存就不同了。到最后,ptr的值还是不变。

这就是值传递。

三,修改后

那么,该如何实现我们所需的目标呢?请看下面的代码(实现方法之一):

#include<iostream>
using namespace std;
void GetMemory(int **ptr, int size)
{
    *ptr = new int[size];
}

int main()
{
    int *ptr = NULL;
	cout<<"第一处,ptr="<<ptr<<endl;

    GetMemory(&ptr, 100);

    cout<<"第二处,ptr="<<ptr<<endl;
    delete[] ptr;
	return 0;
}

这个办法就是使用二级指针作为形参。

在运行到主函数的第三句时,也即GetMemory(&ptr, 100);

这时候,程序就会生成一个&ptr的副本,这个副本的值和&ptr的值相同,都是ptr的地址。

当进入GetMemory函数后,程序将执行*ptr = new int[size];

对于这里的*ptr,我们将其记为*p,就是换个名称,不然容易搞混。

那么,p代表形参,*p代表形参的值,也就是&ptr的副本的值,也就是ptr的地址。对它操作相当于对ptr操作。

这样就改变了ptr的地址。

这就是址传递。

四,题外话

有人可能会问,数组名作实参时,传递的不就是它本身吗?并不是什么副本啊?

数组名其实就是数组的首地址。

数组名作实参时,程序会生成一个数组首元素地址的副本传给形参。

形参和实参共同指向同一段内存,在自定义函数里对形参的操作均会影响到外部的实参。

如果你觉得这篇文章对你有帮助的话,点个赞再走吧。

如有错误,敬请指正,感激不尽。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值