通俗的方式讲解C++参数传递

假设你现在有一本书A, 放在书柜的第二格里。 A的封面上写着数字1, 而你要做的事情是把A的封面上的数字改为2.
很简单,但是你要通过使用C++的函数来完成这件事情。
是不是瞬间就变难了?


C++的参数传递方式有三种: 值传递,引用传递和指针传递。
你现在要做的事情是把A的封面上的数字改为2, 下面说说通过以上三种方式,你(C++)是怎么去做这件事的。

1 值传递

你把A复制出了一本一模一样的书, 记为B.
B的封面上也写着数字1, 然后你把B传给了函数modify1
代码描述就是:

void modify1(int book)
{
    book = 2;
}

int main()
{
    int A = 1; //书A
    modify1(A);
    return 0;
}

函数modify1把B的封面上的数字改为了2, 然后函数modify1的工作就完成了。
但是却没有达到你想要的效果,因为此时A的封面上的数字还是1. 为什么,因为你拿给函数的书是B, 所以改的也是B, 不会影响到A.

所以值传递就是复制一个实参的值传递给函数。 不管函数做了什么事情,都不会影响实参。

2 引用传递

你现在想着,干脆把A本身直接传给函数modify2算了。
代码描述:

void modify2(int& book) //注意&
{
    book = 2;
}

int main()
{
    int A = 1; //书A
    modify2(A);
    return 0;
}

此时你发现A的封面上的数字果然 神奇地 变为了2, 为什么? 因为你拿给函数的书就是A啊
你的任务完成了。

所以引用传递就是把实参本身直接传递给函数,函数做什么事,都是直接操作在实参本身。

3 指针传递

但是你发现引用传递竟然要亲自把书A拿给函数modify2, 如此艰苦的活儿让你感到实在是难以胜任…
路人说,让函数自己去拿书不就行了吗,你的格局瞬间就打开了。

于是你写了一张小纸条,内容是: “书A放在书柜的第二格里”。 并把这个小纸条递给了函数modify3.
代码描述:

void modify3(int* note)
{
    *note = 2;
}

int main()
{
    int A = 1; //书A
    int* note = &A; //note就是你写的小纸条
    modify3(note);
    return 0;
}

于是你 又再次神奇地 发现果然书A的封面上的数字也变成了2。

所以指针传递就是把实参的地址传递给函数,函数做什么事,同样也是直接操作在实参本身。
解释一下,小纸条就是指针,小纸条的内容就是书A的位置(指针的值就是书A的地址)。
你可以这样理解: 函数拿到书A的地址后,函数就会自己去取书A, 所以函数做的事情就是直接操作在书A上。

很好! 你已经精通了C++的三种参数传递机制。


现在,身为参数传递大师的你,经常通过指针传递往书A里写入一些不可告人的秘密…
别问为什么是指针传递,问就是高级。
但是每次函数帮你写完小秘密后,小纸条还留着,并且还保留着书A的位置。
那这样肯定不行啊,绝对不能让别人看到你把书A藏在哪里了。

所以每当函数做完它的事情,你就要把小纸条销毁。

void modify3(int* note)
{
    *note = 520;
}

int main()
{
    int A = 1;
    int* note = &A; //note就是你写的小纸条
    modify3(note);
    note = NULL; //每当函数做完它的事情, 你就要把小纸条销毁
    return 0;
}

嗯,这样就没有人会知道了。
但是身为驰名中外的参数传递大师,如此简单的事情怎么还要你亲自来做。 由于你的格局已经被路人打开过,所以你很快就想到可以让函数来帮你做这件事,既高效又安全。

于是你把那行代码换一下位置就行了,连注释都没改。

void modify3(int* note)
{
    *note = 520;
    note = NULL; //每当函数做完它的事情, 你就要把小纸条销毁
}

int main()
{
    int A = 1;
    int* note = &A; //note就是你写的小纸条
    modify3(note);
    return 0;
}

嗯,不愧是你。

第二天,你身败名裂了。

有人看到了你的小纸条里写的内容,并扒开了你所有的秘密…
明明你已经让函数在写完你的秘密后就把小纸条销毁,为什么小纸条还在?
百思不得其解兼恼羞成怒的你抓起函数直接就是一把乌鸦坐飞机。

然后你发现函数竟然私下藏了一张同样的小纸条!
原来,每次你把你写的小纸条传递给函数时,函数就把你的小纸条的内容抄到它自己的小纸条里,并没有真正使用你的小纸条。 所以函数销毁的也是它自己的小纸条,而不是你的。 因此你的小纸条就被别人看到了。


解释一下,上述的指针传递,本质其实是值传递。 所谓"指针传递",意思其实是函数的形参类型是一个指针。
举个例子:

void func(char c);

这个函数采用的是什么参数传递方式? 当然是值传递,而不是"字符传递"。

void modify3(int* note);

同样地, int* 在这里表明note是一个指针类型,而不是一个"表明参数传递方式的标识符"。

所以说指针传递的本质就是值传递,这就解释为什么函数它会有自己的小纸条,因为是值传递,所以它复制了你的小纸条。

你后悔莫及,你本就应该老老实实地用引用传递而不是为了装X而用指针传递
但是你又怎么可能甘心就用朴素的引用传递呢,怎么说你也曾是个大师…

只见你轻轻按下Shift + 7

void modify4(int*& note)
{
    *note = 520;
    note = NULL; //每当函数做完它的事情, 你就要把小纸条销毁
}

int main()
{
    int A = 1;
    int* note = &A; //note就是你写的小纸条
    modify4(note);
    return 0;
}

事了拂衣去,深藏功与名。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值