You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言指针场景下++*p++与*++p++的区别及后者报错原因

C语言指针表达式++*p++与*++p++的差异说明

核心差异来自C语言的运算符优先级、结合性规则,以及自增运算符对操作数的左值要求,这也是前者合法、后者编译报错的根本原因。

前置规则(C语言标准规定)

先明确涉及的3类运算符的属性,优先级从高到低排序:

  • 后缀自增++:优先级最高,左结合,要求操作数必须是可修改左值,运算返回右值(操作数自增前的临时副本)
  • 前缀自增++、间接寻址*:优先级比后缀自增低1级,右结合;其中前缀自增同样要求操作数是可修改左值、返回左值,间接寻址操作仅要求操作数为指针类型、返回对应类型的左值。

合法表达式++*p++的执行逻辑

按照规则从高到低、同优先级按结合性拆解:

  1. 最先执行后缀p++:p是指针变量,属于可修改左值,符合后缀自增的要求;运算后p本身向后移动1个元素位,返回p自增前的指针值临时副本(右值)
  2. 同优先级右结合,接下来执行间接寻址*:对第一步返回的指针副本做解引用,拿到p自增前所指向的内存位置,是对应类型的可修改左值
  3. 最后执行前缀++:对第二步解引用得到的左值做前缀自增,把该位置存储的值+1,返回自增后的结果,整个流程完全符合语法要求。

报错表达式*++p++的编译错误原因

按同样规则拆解,第二步直接触发语法错误:

  1. 最先执行后缀p++:这一步和上述合法表达式一致,p是合法左值,完成自增后返回p自增前的指针临时副本(右值,不是可修改的左值,和1+2返回的临时计算值属性一致)
  2. 同优先级右结合,接下来要执行前缀++:前缀自增要求操作数必须是可修改的左值,但当前传入的是第一步返回的临时右值,不满足语法要求,编译器直接抛出错误,后续的间接寻址*根本不会被执行。

这个错误本质和写++(3+5)报错是同一个逻辑:不能对一个临时的计算结果做自增操作,临时值没有对应的可修改内存空间,无法存放自增后的结果。

测试代码相关说明

给出的测试代码报错点为printf("%d ",*++ptr++);行,如果要实现「指针移动一位后取值,再移动一位」类逻辑,不建议堆砌复杂的连续自增表达式,拆成分步写法即可,可读性和稳定性更高,示例写法:

#include <stdio.h>
int main()
{
    int arr[]={3,9,0,4,5};
    int *ptr=arr;
    ++ptr;
    printf("%d ",*ptr);
    ++ptr;
    printf("%d ",*ptr);
    return 0;
}

连续自增搭配解引用的写法本身可读性极差,即使语法合法也极易触发未定义行为,生产环境代码不推荐使用。

内容的提问来源于stack exchange,提问作者NEHA G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:51:23