[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;
posted @ 2011-03-27 18:25  zsounder  阅读(894)  评论(0编辑  收藏  举报