C语言修改数组后如何恢复原状态 使后续指针操作作用于原数组
问题根因
++*p和++(*p)的执行逻辑完全等价:C语言中前置自增++和解引用*优先级相同,结合方向为从右到左,所以语句执行时会先解引用指针p拿到它指向的原数组arr[0]的内存,再直接对这块内存里的值做+1修改。
你第一次执行语句后arr[0]已经从初始的10被改成了11,第二次执行相同语句时会在11的基础上继续+1得到12,自然不符合预期的11结果。
可行实现方式
你可以根据实际场景选以下任意一种方案:
- 保存原始值后恢复
第一次修改数组前先把首元素的原始值存到临时变量,第一次打印完成后把原始值写回原数组,后续语句就会基于初始值执行:int arr[] = {10,20,30,40,50}; int *p = arr; int a, origin_first; origin_first = *p; // 提前存好arr[0]的初始值10 a = ++*p; printf("第一次操作后arr[0] = %d\n", arr[0]); // 输出11 *p = origin_first; // 恢复首元素为初始值 a = ++(*p); printf("第二次操作后arr[0] = %d\n", arr[0]); // 输出11,符合预期 - 不直接修改原数组,仅做值计算
如果你不需要真的改动数组元素,只是要拿到自增后的计算结果,直接读取指针指向的值做算术计算即可,不会改动原内存的数据:int arr[] = {10,20,30,40,50}; int *p = arr; int a; a = *p + 1; printf("第一次计算a = %d, arr[0] = %d\n", a, arr[0]); // a=11, arr[0]保持10 a = (*p) + 1; printf("第二次计算a = %d, arr[0] = %d\n", a, arr[0]); // a=11, arr[0]保持10 - 用临时指针操作值副本
如果你的后续逻辑必须保留++(*p)的指针操作写法,可以创建一个临时变量存初始值,让临时指针指向这个副本,操作副本不会影响原数组:int arr[] = {10,20,30,40,50}; int *p = arr; int a; a = ++*p; printf("第一次操作后arr[0] = %d\n", arr[0]); // 输出11 int temp_val = 10; // 存原始值 int *p_temp = &temp_val; a = ++(*p_temp); // 操作的是临时副本,不碰原数组 printf("副本操作得到a = %d\n", a); // a=11,符合计算预期
注意
不要混淆前置自增和后置自增的逻辑,只要是对解引用后的指针指向内存做前置/后置自增,都会直接修改原数组对应位置的值,不存在自动生成临时副本的机制。
内容的提问来源于stack exchange,提问作者ayushkadbe
相关产品推荐
相关产品推荐

