|
一、为什么普通函数无法修改外部变量? 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修改的是指向的内容,不是指针本身 一句话口诀:普通传参改副本,指针传参改原件。&给地址,*开门改! 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |