C++自增运算符的理解

文章详细解释了C++中的前置自增(`++operator`)和后置自增(`operator++(int)`的实现原理,并通过代码示例展示了它们在表达式中结合不同操作时的行为差异,特别是在涉及指针和常量时的注意事项。文章强调了优先级和结合方向在解析表达式中的作用,并给出了不同写法可能导致的不同结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前置自增和后置自增原理:

两种运算符的内部如下,参数int是为了区分前置和后置++,后面不跟变量。

同时建议平常尽量使用前置++,因为没有额外的性能损耗。

// 前置自增
T &operator++() {
    this = this + 1;
    return *this;
}

// 后置自增
T operator++(int) {
    T tmp = this;
    this = this + 1;
    return tmp;
}

*p++

由于++和*的优先级是一样的,而等级相同时结合方向时从右向左,故先计算++,再计算*;同时++操作符返回的是一个临时值,即返回的p再进行的++,等同于*(p++);

(*p)++

先计算*,再计算++;

*++p

运算符同级,从右向左,先计算++,再计算*;

++*p

运算符同级,从右向左,先计算*p,再计算++;

在上述理论上,对于不同的赋值情况可能会产生不同的效果,如下test2中的 (*p)++,编译器认为*p提取出来的是一个常量字符,故不能对齐做出修改操作,所以在这种情况下写法是有问题的。

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <set>
#include <queue>

using namespace std;

void test1() {
  // *p++ 等同于 *(p++)
  int arr[] = {1, 4, 7, 9, 10};
  int *p = arr;
  int a = *p++;
  // 1 4
  cout << a << " "<< *p << endl;

  // (*p)++
  p = arr;
  int b = (*p)++;
  // 1 2
  cout << b << " " << *p << endl;

  // *++p
  p = arr;
  int c = *++p;
  // 4 4
  cout << c << " " << *p << endl;

  // ++*p
  p = arr;
  int d = ++*p;
  // 3 3
  cout << d << " " << *p << endl;
}

void test2() {
  char *c = "abcdef";
  char *p = c;
  char t;

  // *p++
  t = *p++;
  // a b
  cout << t << " " << *p << endl;

  // // (*p)++
  // p = c;
  // t = (*p)++;
  // // 可以看到,这里输出不了,因为编译器认为 t 对应的是常量字符
  // // 故不存在 ++ 操作
  // cout << t << " " << *p << endl;

  // *++p
  p = c;
  t = *(++p);
  // b b
  cout << t << " " << *p << endl;

  // ++(*p)
  p = c;
  t = ++(*p);
  // 同 (*p)++
  cout << t << " " << *p << endl;
}

int main(){
  test1();
  test2();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值