C语言中引用传递的骗局
传入 **p 还是传入 *p
在以前的 C 教科书上,一直教导我们, C 语言函数有两种传递参数的方式:值传递和引用传递。 但是,今天在看 c-faq
的 4.11
的时候,才了解到真相。其实严格意义上来讲, C 语言只有值传递,但是编译器可以模拟引用传递,但本质上,还是值传递。 举个例子:
1 |
|
这是一个很正常的指针传递,我们一般把这个称为引用传递。对于整数 i 来说,确实是这样的,但是对于 int
指针来说, f
函数调用,只是把 i 的地址复制一份给 p ,这个行为其实是在传值。 可能这个例子不是很明显,那么引用一下 c-faq
上的一个例子:
1 |
|
指针 i
在 f
函数调用后,是否改变了?答案是没有,因为 f(i)
是一个传值,只是复制了一份 i
的值而已,尽管在 f
函数内部改变了,但是只是改变了 i
的复制版。这其实是 C 语言初学者,经常犯的错误,把传值理解为传地址。但是为什么还是有很多人在这个代码上,犯糊涂了?因为我们习惯上把传指针直接当作引用传递的替身了。
其实,我们为了传递一个指针的引用,应该用指针的指针:
1 |
|
这样,对于指针 **p
来说, f
函数是传值,但是对于指针 *p
来说,其实是传地址,跟上面是一个道理。
其实还可以如下修改:
1 |
|
这样,对于指针 *p
来说, f
函数是传值,但是对于整数 i
来说,其实是传地址,跟上面是一个道理。
参考资料
C语言中引用传递的骗局
https://ysc2.github.io/ysc2.github.io/2024/04/21/C语言中引用传递的骗局/