ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

c语言中函数传递二级指针,修改指针指向

c语言中函数传递二级指针,修改指针指向
#include<stdio.h>voidtry_change_ptr(int*p){// 发现p指向的地址和ptr指向的地址一样,但是p本身的地址和ptr本身的地址不一样printf("Inside function, p = %p, &p = %p\n",(void*)p,&p);// 所以可以修改p指向的内容*p=1;// 但修改不了ptr的指向地址,因为p是一个拷贝,p本身的地址和ptr本身的地址不一样p=NULL;// 修改的是函数内部的 p(副本)printf("Inside function, p = %p, &p = %p\n",(void*)p,&p);}intmain(){inta=10;int*ptr=&a;printf("&a %p\n",&a);printf("%d\n",*ptr);// 打印ptr的指向地址和ptr本身的地址printf("Before call, ptr = %p, &ptr = %p \n",(void*)ptr,&ptr);//这里会创建副本,就像int fun(int a) 传入a一样,如果要修改a的地址,就要传a的地址try_change_ptr(ptr);printf("After call, ptr = %p, &ptr = %p \n",(void*)ptr,&ptr);// 仍然是 &a!没变!printf("%d\n",a);return0;}/* &a 0000002274F4FB60 10 Before call, ptr = 0000002274F4FB60, &ptr = 0000002274F4FB68 Inside function, p = 0000002274F4FB60, &p = 0000002274F4FB40 Inside function, p = 0000000000000000, &p = 0000002274F4FB40 After call, ptr = 0000002274F4FB60, &ptr = 0000002274F4FB68 1 *//*如果你不仅想修改内容,还想在函数内部改变原指针的指向,你需要使用二级指针(指针的指针)。 这就像你不仅拿到了钥匙,还拿到了“存放钥匙的保险箱的钥匙”。*///void changePointer(int **p) {// **p = 200; // 依然可以修改内容// *p = NULL; // 成功修改了外部指针的指向!//}//int main() {// int a = 10;// int *ptr = &a;// changePointer(&ptr); // 注意这里传的是 ptr 的地址// // 此时 ptr 已经变成了 NULL// return 0;//}/* * 输出打印 Before call, ptr = 0060FE98 Inside function, *p = 10 Inside function, p = 00000000 After call, ptr = 0060FE98 *///void really_change_ptr(int **pp)//{// //和a的地址相同// printf("Inside function, *pp = %p\n", *pp);// printf("Inside function, **pp = %d\n", **pp);// *pp = NULL; // 通过 pp 修改它指向的那个指针变量// printf("Inside function, pp = %p\n", (void *) pp);// printf("Inside function, *pp = %p\n", *pp);//}//int main()//{// int a = 10;// printf("a add: %p\n", &a);// int *ptr = &a;// printf("Before: %p\n", (void *) ptr);// //这里要修改指针的地址,就要通过指针类型,传指针的地址// really_change_ptr(&ptr); // 传 ptr 的地址// printf("After: %p\n", (void *) ptr); // 现在变成 NULL 了!//}/* a add: 0060FE9C Before: 0060FE9C Inside function, *pp = 0060FE9C Inside function, **pp = 10 Inside function, pp = 0060FE98 Inside function, *pp = 00000000 After: 00000000 */

在 C/C++ 中,*ptr++是一个非常经典且高频使用的表达式。它的核心逻辑可以总结为一句话:先取当前指针指向的值,然后将指针向后移动一个单位。

为了让你彻底弄懂,我们从底层原理到实际代码进行拆解:

1. 底层原理:运算符优先级与结合性

在这个表达式中,同时出现了*(解引用)和++(后置自增)。
根据 C/C++ 的语法规则:

  • 后置++的优先级高于*
  • 当优先级相同时,结合方向是从右向左。

因此,*ptr++在编译器眼中等价于*(ptr++)

2. 具体执行步骤

假设ptr是一个指向数组的指针,*(ptr++)的执行过程分为两步:

  1. 取值:先对当前的ptr进行解引用,获取它当前指向的内存中的值。
  2. 移动指针:随后,ptr自身的地址发生偏移,指向下一个元素(步长取决于指针的类型,例如int*会向后移动 4 个字节)。

⚠️ 核心注意点:这个表达式只改变了ptr的指向,并没有修改原来内存位置里的数据值。

3. 代码演示

我们来看一段直观的代码:

#include<stdio.h>intmain(){intarr[]={10,20,30};int*ptr=arr;// ptr 初始指向 arr[0]// 使用 *ptr++intval=*ptr++;printf("取出的值 val = %d\n",val);// 输出: 10printf("当前指向的值 *ptr = %d\n",*ptr);// 输出: 20return0;}

结果解析:val拿到了旧值10,而ptr已经悄悄向后移动,现在指向了20

4. 易混淆对比(避坑指南)

初学者经常把*ptr++和下面这两个表达式搞混,它们的区别非常大:

表达式等价形式作用对象结果
*ptr++*(ptr++)指针本身取出旧值,指针向后移动,数据不变
(*ptr)++(*ptr)++指向的数据取出旧值,数据加 1,指针不动
*++ptr*(++ptr)指针本身指针先向后移动,再取出新位置的值

💡 总结与应用

*ptr++这种“先取值,后移动”的特性,非常适合用来顺序遍历数组。在底层 C 语言开发中,它能让遍历数组的代码变得非常简洁优雅,不需要像arr[i++]那样单独写一行ptr++

返回列表