C++ 的 ++i 与 i++:结果相同,时机不同

一句话:都给 i 加 1。区别在表达式本身等于什么:++i 交回新值;i++ 先交回旧值再加一。单独成行时,两者完全一样。

跑这个 — 两个变量初值相同,唯一区别是前置/后置自增:

#include <iostream>
using namespace std;

int main() {
    int i = 5;
    cout << "i++ gives: " << i++ << ", i is now " << i << endl;

    int j = 5;
    cout << "++j gives: " << ++j << ", j is now " << j << endl;
    return 0;
}

i++ 打印了 5 — 旧值 — 然后才变成 6。++j 先变成 6,再把新值打出来。全部区别就这些:表达式的值。

逐步拆解

循环里有区别吗?完全没有

下面两个循环输出一模一样 — 循环只用自增的副作用,从不用表达式的值:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 5; i++) cout << i << " ";
    cout << endl;
    for (int i = 0; i < 5; ++i) cout << i << " ";
    cout << endl;
    return 0;
}

那什么时候真有区别?不在 int 上 — 编译器把两者优化成同样的机器码。区别在类类型:i++ 必须保留一份旧值交还,大对象的拷贝就是真开销。所以 C++ 风格指南说:习惯性用 ++i — 不会更慢,偶尔更快。

著名的陷阱:一条语句两次自增

永远别写这种东西,哪怕"试一试":

i = i++ + ++i;   // 未定义行为 — 不要使用

一个变量在两个"序列点"之间(粗略说:同一条语句内,且没有确定的顺序保证)被修改两次时,标准拒绝说明会发生什么。不同编译器给出不同答案,优化编译器甚至可能产出任何东西。一条语句一次自增,保你平安。

相关面试题

  1. "cout << i++ 打印什么?" — i 的旧值;之后 i 大一。
  2. "++i 和 i++ 哪个快?" — 内建类型优化后一样;类类型前置可能少一次拷贝。
  3. "i = i++ 为什么是坏的?" — 一条语句里两次修改 i,无顺序保证,未定义行为。
  4. "运算符重载在这里是什么?" — 类类型定义 operator++(int)(后置,哑 int 参数)和 operator++()(前置);那个哑参数就是 C++ 区分两者的手段。

去练习场练手

  1. 预测 int a = 3; int b = a++; cout << a << b; 的输出 — 再跑。(答案:4 和 3。)
  2. 换成 ++a — 什么变了?
  3. 把 i++ 和 ++i 分别放进 for 循环表头,确认输出一致。

相关:for 与 while 循环、为什么 7/2 等于 3、初学者面试题。