关键在表达式返回值:前置++返回新值,后置++返回旧值;变量均在子表达式求值期间加1;位置决定“交值”时机,嵌入运算只认该值;多次修改同一变量属未定义行为。

关键不在“谁先加1”,而在“整个表达式用哪个值”——前置++返回新值,后置++返回旧值;变量本身都会加1,且都在该子表达式求值期间完成。
看位置,定返回值
运算符紧贴变量左侧(如 ++i),表示“先改再交值”;贴右侧(如 i++),表示“先交值再改”。这个“交值”,就是它在整个表达式中贡献的那个数。
-
++i:i 原来是 7,执行后 i=8,整个
++i子表达式的值就是 8 -
i++:i 原来是 7,整个
i++子表达式的值就是 7,之后 i 才变成 8
嵌在算术或赋值里,只认那个“交出来的值”
别被“加1动作发生得早或晚”带偏。真正影响结果的,是这个子表达式向上一级提供的数值。
-
int x = 3; int y = x++ + 1;→x++交出 3,y = 3 + 1 = 4,之后 x=4 -
int x = 3; int y = ++x + 1;→++x交出 4,y = 4 + 1 = 5,x 已是 4 -
arr[i++] = val;→ 用 当前 i 当下标存值,存完 i 才+1 -
arr[++i] = val;→ 先 i+1,再用 新 i 当下标,可能越界
警惕未定义行为:别在一个表达式里多次改同一变量
C/C++标准规定,若无明确序列点分隔,对同一变量做多次修改(比如 i++ + ++i)属于未定义行为——结果不可预测,编译器可任意处理,必须避免。
- ✅ 安全:
y = i++ + 5;(只改一次 i) - ✅ 安全:
y = ++i + 5;(只改一次 i) - ❌ 危险:
y = i++ + ++i;(两次修改 i,无序列点) - ❌ 危险:
a[i++] = a[++i];(i 被读、写、改多次)
效率与实现细节(附带提醒)
前置++通常比后置++稍快,因为后者需临时保存原值再返回(相当于多一个中间量)。但这在现代编译器优化下常可忽略;真正重要的是语义清晰——你要的是“改完立刻用”,还是“先用旧值再挪位”。
- 循环更新(
for (int i = 0; i < n; i++))中二者等效,因不依赖返回值 - 但写成
if (valid[i++]) process(i);就容易逻辑错位——i 已跳过一位才进入处理 - 重载运算符时,前置常返回
T&(引用),后置常返回T(值),也印证了“是否要保留旧态”的设计意图

















