『7x24小时有问必答』

一、为什么普通函数无法修改外部变量?

C语言的函数参数传递默认是值传递,也就是说,函数接收的是实参的副本,而不是实参本身。
void  change(int  x)  {

      x =  100;   // 修改的是副本,不影响外部

}

int  main()  {

int  a =  10;

      change(a);

printf("%d", a);   // 输出:10(没有改变!)

return0;

}
原因:函数内部的x和外面的a在内存中是完全不同的两块空间。函数拿到的是a的“复印件”,你在复印件上涂改,原件当然不会变。

二、指针如何实现“隔空修改”?

指针就是存储地址的变量。当你把地址传给函数时,函数就能通过这个地址找到原始变量并直接修改它。
void  real_change(int  *p)  {

      *p =  100;   // *p 表示“通过地址找到原始变量,修改它”

}

int  main()  {

int  a =  10;

      real_change(&a);   // &a 表示“把a的地址传过去”

printf("%d", a);   // 输出:100(成功改变!)

return0;

}
关键就是两个符号
&
:取地址符,告诉我“你在哪儿?”
*
:解引用符,找到那个地址,“开门进去修改内容”

三、一句话记住核心原理

普通传参  = 你把照片给朋友,朋友在照片上画胡子,你的脸没事。

指针传参  = 你把家庭住址告诉朋友,朋友直接来你家搬东西。

四、经典案例:交换两个变量的值

这是指针传参最经典的面试题:
//  错误:值传递,交换的是副本

void  swap_wrong(int  a,  int  b)  {

int  temp = a;

      a = b;

      b = temp;

}

//  正确:指针传递,交换的是原始变量

void  swap_right(int  *a,  int  *b)  {

int  temp = *a;

      *a = *b;

      *b = temp;

}

int  main()  {

int  x =  3, y =  5;

      swap_wrong(x, y);

printf("x=%d, y=%d\n", x, y);   // 输出:3, 5(没变)

      swap_right(&x, &y);

printf("x=%d, y=%d\n", x, y);   // 输出:5, 3(成功交换!)

return0;

}

五、常见误区与注意事项

误区1:试图修改指针本身,而不是它指向的内容

void  try_change_ptr(int  *p)  {

int  b =  20;

      p = &b;   //  这只是修改了局部指针副本的指向

}

// 调用后,外面的指针依然指向原来的变量
原理:指针传参本身也是值传递!函数收到的是指针的副本,这个副本和原指针指向同一块内存。你可以通过*p修改那块内存的内容,但如果修改p本身(让它指向别处),外面的原指针不受影响。

误区2:对空指针或无效指针解引用

void  modify(int  *p)  {

      *p =  100;   // 如果p是NULL,程序会崩溃!

}
安全做法:解引用前检查指针是否为空。

误区3:返回局部变量的地址

int*  create_int()  {

int  x =  10;

return  &x;   //  函数结束后x被销毁,地址无效

}

六、实际应用场景

返回多个值
:通过多个指针参数,一个函数可以“返回”多个结果
修改大型数据结构
:传地址比传整个结构体副本高效得多
操作数组
:数组名本身就是指针,传数组本质就是传地址
链表操作
:插入、删除节点时,需要通过指针修改节点间的连接关系

总结

核心要点
&
取地址,*解引用——这两个符号搞懂就掌握了80%
指针传参让函数能直接操作外部变量的内存
牢记:你通过*p修改的是指向的内容,不是指针本身
一句话口诀:普通传参改副本,指针传参改原件。&给地址,*开门改!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码