泰晓科技 -- 聚焦嵌入式 Linux - 追本溯源,见微知著!
网站地址:http://tinylab.org
微信公众号关注我们新浪微博


扫一扫

关注 @泰晓科技
原创服务 | 实验云台 | 共享书籍 | 开放源码
请稍侯

[c-faq] 4.8-引用传递的骗局

Wen Pingbo 创作于 2013/08/25

by Pingbo Wen of TinyLab.org 2013/08/24

在以前的 C 教科书上,一直教导我们, C 语言函数有两种传递参数的方式:值传递和引用传递。 但是,今天在看 c-faq 的 4.11 的时候,才了解到真相。其实严格意义上来讲, C 语言只有值传递,但是编译器可以模拟引用传递,但本质上,还是值传递。 举个例子:

void f(int *p);
//...
int i;
f(&i);

这是一个很正常的指针传递,我们一般把这个称为引用传递。对于整数 i 来说,确实是这样的,但是对于 int 指针来说, f 函数调用,只是把 i 的地址复制一份给 p ,这个行为其实是在传值。 可能这个例子不是很明显,那么引用一下 c-faq 上的一个例子:

void f(int *p)
{
    static int dummy=5;
    p=&dummy;
}
//...
int *i;
f(i);

指针 i 在 f 函数调用后,是否改变了?答案是否,因为 f(i) 是一个传值,只是复制了一份 i 的值而已,尽管在 f 函数内部改变了,但是只是改变了 i 的复制版。这其实是 C 语言初学者,经常犯的错误,把传值理解为传地址。但是为什么还是有很多人在这个代码上,犯糊涂了?因为我们习惯上把传指针直接当作引用传递的替身了。其实,我们为了传递一个指针的引用,应该用指针的指针:

void f(int **p)
{
    static int dummy=5;
    *p=&dummy;
}
//...
int *i;
f(&i);

这样,对于指针 **p 来说, f 函数是传值,但是对于指针 *p 来说,其实是传地址,跟上面是一个道理。


Read More: