彻底理解 C++ 的递增(++)与递减(--)运算符(五十四)

1. 两种形式:前置 vs. 后置

  • 前置形式++x--x

    1. x 加(减)1
    2. 返回 修改后x(左值)
  • 后置形式x++x--

    1. 保存 x 的当前值(临时副本)
    2. x 加(减)1
    3. 返回 修改前 的临时副本(右值)
int i = 0, j;

// 前置 ++:i 先自增,返回增后的值
j = ++i;    // i == 1, j == 1

i = 0;
// 后置 ++:保存 i 的旧值,i 自增,然后返回旧值
j = i++;    // i == 1, j == 0

注意

  • 前置版本返回的是一个 左值(仍指向原对象),可继续被赋值;
  • 后置版本返回的是一个 右值(原值的副本),不可做左值。

2. 优先级与结合律

  • 优先级

    • 后置 x++ / x-- 优先级高于一元解引用 *x
    • 其余与乘除算术运算同级,均高于加减
  • 结合律
    所有增减运算符均为 右结合(与赋值类似),不过通常不需要链写。

3. 与解引用结合:常见范例

最常见的“看似魔法”写法,用于迭代器或指针遍历:

auto it = v.begin();
while (it != v.end() && *it >= 0) {
    // 输出当前元素,再将 it 后移一位
    std::cout << *it++ << " ";
}

等同于:

while (it != v.end() && *it >= 0) {
    std::cout << *it << " ";
    ++it;
}
  • *it++ 先取 it 的旧值(指向当前元素),解引用输出;
  • 再对 it 执行后置自增,指向下一个元素。

警告
不要写成 *it = toupper(*it++) 那样同时对同一表达式左、右两侧使用后置增减,会造成未定义行为——因为求值顺序不确定,修改与访问同一对象冲突。

4. 求值顺序与未定义行为

C++(直到 C++17)并未保证二元操作中左右操作数的求值顺序,混合修改和读取同一对象会导致未定义行为

int beg = 0;
char s[] = "Hello";
while (beg < strlen(s) && !isspace(s[beg])) {
    s[beg] = toupper(s[beg++]);  // ❌ 未定义行为!
}
  • s[beg++] 会修改 beg
  • 同一个表达式中 s[beg] 访问它。
  • 编译器可先后任意求值,结果不可预测。

避免办法

  • 将“修改”与“访问”拆成两条语句;
  • 或明确序列点/C++17 强化的顺序保证。

5. 最佳实践

  1. 前置首选

    • 对原始数值型做增减,使用 ++x / --x
    • 唯有在需要“使用旧值,之后再增减”的场景(如迭代器输出)才用后置。
  2. 避免副作用冲突

    • 不要在同一表达式中既修改又访问同一对象;
    • 拆分或明确顺序:
      char c = s[beg];
      s[beg] = toupper(c);
      ++beg;
      
  3. 清晰胜于省略

    • 虽然 *it++ 多见,但初学者建议写成两步:cout<<*it; ++it;,更易读、少出错。
  4. 遵循现代 C++

    • C++17 后标准库算法(std::transformstd::for_each)和范围 forfor (auto &ch : s) ch = toupper(ch);)常能替代手写指针/迭代器。

小结

  • 前置 (++x):先增减,返回新值(左值);
  • 后置 (x++):先返回旧值(右值),再增减;
  • 注意优先级:后置增减高于解引用;
  • 绝不在单一表达式内既修改又访问同一对象
  • 尽量用现代算法与范围 for,让代码更简洁安全。

熟练掌握增减运算符,将让你在指针运算、迭代器遍历与性能关键代码中游刃有余!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello.Reader

请我喝杯咖啡吧😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值