前置自增和后置自增原理:
两种运算符的内部如下,参数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();
}