[cpp] 前置后置操作符总结
我没参加过笔试呢,不过经常有人拿着笔试中的问题来问我,特别是++、--运算符的问题, 其实这些问题应该从基本原理上理解一下,但是在笔试中这种问题还是有个简单的方法计算才好。总结以下的几条:
1) 在计算中,对于一个作用域内的前缀操作数(++i),替换为i的最终数值,对于后缀操作符替换为原数值。
2) 在printf,cout等依靠堆栈工作的方法中,对于一个作用域内的前缀操作符(++i),替换为i的最终数值,对于后缀操作符,按照入栈顺序分析。
1: int a ;
2: //------------------------------------------------------------------------------------
3: // 以下部分, 不含有前缀操作符, 首先是后面的a++入栈1,a=2,后是第一个a++入栈2
4: a = 1;
5: cout<<"a "<<a++<<" "<<a++<<endl; //2,1
6: cout<<"a "<<a<<endl; //3
7: a = 1;
8: printf("a %d %d\n",a++,a++); //2,1
9: printf("a %d\n",a); //3
10:
11: //------------------------------------------------------------------------------------
12: // 以下部分, 含有前缀操作符,计算a的最终数值为3 首先是++a入栈为3,之后是++a入栈为3
13: a = 1;
14: cout<<"a "<<++a<<" "<<++a<<endl; //3,3
15: cout<<"b "<<a<<endl; //3
16: a = 1;
17: printf("a %d %d\n",++a,++a); //3,3
18: printf("a %d\n",a); //3
19:
20: //------------------------------------------------------------------------------------
21: // 以下部分, 含有前缀操作符, 计算a的最终数值为3,首先是++a入栈为3,a=2之后是a++入栈为2
22: a = 1;
23: cout<<"a "<<a++<<" "<<++a<<endl; //2,3
24: cout<<"a "<<a<<endl; //3
25: a = 1;
26: printf("a %d %d\n",a++,++a); //2,3
27: printf("a %d\n",a); //3
28:
29: //------------------------------------------------------------------------------------
30: // 以下部分, 含有前缀操作符, 计算a的最终数值为3,首先是a++入栈为1,a=2之后是++a入栈为3
31: a = 1;
32: cout<<"a "<<++a<<" "<<a++<<endl; //3,1
33: cout<<"a "<<a<<endl; //3
34: a = 1;
35: printf("a %d %d\n",++a,a++); //3,1
36: printf("a %d\n",a); //3
37:
38: int b;
39: a = 1;
40: b = 1;
41: // 左右操作符号都是b++,不含有前缀操作符,则左右操作数都替换为1,a=1+1=2
42: a = (b++)+(b++);
43: printf("a = (b++)+(b++) %d %d\n",a,b);//2,3
44: a = 1;
45: b = 1;
46: // 含有前缀操作符,前缀操作符替换为3,a=3+3=6
47: a = (++b)+(++b);
48: printf("a = (++b)+(++b) %d %d\n",a,b);//6,3
49: a = 1;
50: b = 1;
51: // 由于含有前缀操作符,则含前缀操作符的部分替换为3,含后缀操作符的还是原数值,a=3+1=4
52: a = (++b)+(b++);
53: printf("a = (++b)+(b++) %d %d\n",a,b);//4,3
54:
55: a = 1;
56: b = 1;
57: // 由于含有前缀操作符,则含前缀操作符的部分替换为6,含后缀操作符的还是原数值1,a=6+6+6+1+1=20
58: a = (++b)+(++b)+(++b)+(b++)+(b++);
59: printf(" a = (++b)+(++b)+(++b)+(b--) %d %d\n",a,b); //20,6
而对于重载的++、--操作符,情况类似,如下例子,注意第22行代码:
1: class Example{
2: public:
3: Example(int i,int j) { _x = i; _y = j;}
4: // 前缀形式(++i)重载的时候没有虚参,通过引用返回*this,也就是返回变化之后的数值
5: const Example& Example::operator++ () {
6: ++_x;
7: ++_y;
8: return *this;
9: }
10: // 后缀形式(i++)重载的时候有一个int类型的虚参, 返回原状态的拷贝
11: const Example Example::operator++ (int) {
12: Example tmp(*this);
13: ++_x;
14: ++_y;
15: return tmp;
16: }
17: int _x, _y;
18: };
19: Example ei(1,2);
20: cout<<"ei "<<(ei++)._x<<" "<<ei._y<<endl; // 1,2 ei++的时候,返回的是ei原状态的拷贝,此时原ei的状态已经更新
21: cout<<"ei "<<(ei)._x<<" "<<ei._y<<endl; // 2,3 ei的状态已经更新,_x = 2, _y = 3
22: cout<<"ei "<<(++ei)._x<<" "<<ei._y<<endl; // 3,3 首先是ei._y入栈,此时ei尚未更新,入栈为3,之后入栈(++ei)._x,ei已经更新,入栈为3
23: cout<<"ei "<<(ei)._x<<" "<<ei._y<<endl; // 3,4 ++ei的时候,ei已经更新,_x = 3, _y = 4;