C语言中*p++与*p +=1的区别及代码异常原因解析
问题分析:指针自增操作符导致数组遍历异常
核心原因:运算符优先级与结合性
你遇到的问题根源在于运算符优先级和结合性:
- 后缀
++的优先级高于解引用*,且后缀++是右结合,所以*p++等价于*(p++)。这行代码的实际行为是:先读取当前指针p指向的值(但此处未使用这个值,属于无效操作),然后将指针p本身自增1,直接指向数组的下一个元素——根本没修改当前指向的数组元素。 - 而
(*p) += 1是先通过括号强制提升解引用*的优先级,先拿到p指向的元素,再给该元素的值加1,指针p本身不会移动(for循环的p++已经负责指针遍历)。
原代码执行流程拆解
原代码的for循环每一轮的执行步骤是:
- 初始
p指向a[0] - 执行
*p++:读取a[0]的值(无实际作用),然后p自增指向a[1] printf输出*p,也就是a[1]的值1- 循环末尾的
p++让p再次自增,指向a[2]
下一轮循环重复这个逻辑:操作a[2]但不修改它,指针跳到a[3]后输出值3……最终只会输出数组中奇数位置的元素,且原数组的元素根本没被自增。
换成(*p) += 1后,每一轮是先修改当前指向的元素,再输出该元素,循环末尾的p++移动指针到下一个元素,自然得到符合预期的结果。
修正后的代码
把*p++改成(*p)++或者(*p) += 1都能解决问题,示例如下:
#include <stdio.h> #define N 10 int main(void) { int a[N] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, *p; for (p = &a[0]; p < &a[N]; p++) { (*p)++; // 等价于 (*p) += 1 printf("%d ", *p); } return 0; }
总结
*p++和(*p)++完全不是一个意思:前者是指针本身自增,后者是指针指向的元素自增- 写指针操作时,一定要通过括号明确优先级,避免因运算符优先级规则导致的逻辑错误
内容的提问来源于stack exchange,提问作者Bruno Fernandes
相关产品推荐
相关产品推荐

