[置顶] 泰晓 RISC-V 实验箱,配套 30+ 讲嵌入式 Linux 系统开发公开课
[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
来说,其实是传地址,跟上面是一个道理。
猜你喜欢:
- 我要投稿:发表原创技术文章,收获福利、挚友与行业影响力
- 知识星球:独家 Linux 实战经验与技巧,订阅「Linux知识星球」
- 视频频道:泰晓学院,B 站,发布各类 Linux 视频课
- 开源小店:欢迎光临泰晓科技自营店,购物支持泰晓原创
- 技术交流:Linux 用户技术交流微信群,联系微信号:tinylab
支付宝打赏 ¥9.68元 | 微信打赏 ¥1.00元 | |
请作者喝杯咖啡吧 |
Read Album:
- [c-faq] 6.11-数组怪异写法
- [c-faq] 3.8-未定义行为与sequence point
- [c-faq] 3.16-左值和右值
- [c-faq] 2.14, 2.15-offsetof和struct成员异类访问
- [c-faq] 2.10-designated initializer