int a = 10 ,b = 6 ; cout << a + b << " " << a ++<< " " << b ++ ;
请说出上述语句的执行结果。 很多人看过这段代码后估计都会直接就写上了 16 10 6 这样的结果吧,但上机实验的输出结果是: 18 10 6 为什么会出现这样的结果,下面是我的分析过程,如果有不对的地方请大家指正。 为了跟踪代码的执行步骤,我设计了一个类X,这个类是对int的模拟,行为方面与int基本一致,除了会打印出一些帮助我们理解的信息,代码如下: class X { public : X(){cout << " default construct " << endl;} X( int a):i(a){ cout << " construct " << i << endl;} ~ X(){ cout << " desconstruct " << i << endl;} X( const X & x):i(x.i) { cout << " copy construct " << i << endl; } X & operator ++ () { cout << " operator ++(pre) " << i << endl; ++ i; return * this ; } const X operator ++ ( int ) { cout << " operator ++(post) " << i << endl; X x( * this ); ++ i; return x; } X & operator = ( int m) { cout << " operator =(int) " << endl; i = m; return * this ; } X & operator = ( const X & x) { cout << " operator =(X) " << endl; i = x.i; return * this ; } / friend ostream & operator << (ostream & os, const X & x) { os << x.i; return os; } friend X operator + ( const X & a, const X & b) { cout << " operator + " << endl; return X(a.i+b.i); } // public : int i; };
然后执行以下代码: X a( 10 ),b( 6 ); cout << " sum: " << a + b << " a: " << a ++<< " b: " << b ++<< endl;
使用GCC4。5编译后,代码的执行结果如下: construct 10
construct 6
operator ++(post) 6
copy construct 6
operator ++(post) 10
copy construct 10
operator +
construct 18
sum:18 a:10 b:6
desconstruct 18
desconstruct 10
desconstruct 6
desconstruct 7
desconstruct 11
我们来简单分析下这个执行过程:
construct 10
construct 6 //这两行输出对应于 X a(10),b(6);
operator ++(post) 6
copy construct 6 //表明首先执行了 cout<<"sum:" <<a+b<<" a:"<<a++<<" b:"<<b++<<endl;这句中的 b++这个表达式, b++这个表达式返回了一个值为6的临时对象,而b本身则变成了7。
operator ++(post) 10 copy construct 10 //这句的分析同上
operator +
construct 18 //对应于表达式 a+b ,可以看到,此时的a和b已经变成了11和7。表达式返回了一个值为18的临时对象。
sum:18 a:10 b:6 //输出的结果,从结果可以看出,实际上打印出的值分别为 a+b,a++和b++三个表达式所返回的临时变量。
desconstruct 18 //a+b 表达式返回的临时变量的析构
desconstruct 10 //a++ 表达式返回的临时变量的析构
desconstruct 6 //b++表达式返回的临时变量的析构
desconstruct 7 //变量a 的析构
desconstruct 11 //变量b的析构
真相大白了。为什么编译器会这样来编译这个表达式呢?
其实<<在同一语句中连续使用,其实本质上是函数的复合调用: cout<<a+b<<" "<<a++<<" "<<b++; 本质上是 operator<<(operator<<(operator<<(cout,a+b),a++),b++) 由于c++函数的参数的求值顺序是从右至左的(c++标准虽未规定,但是基本所有的编译器是这么干的),所以参数的计算次序是: b++ //7 a++ //11 a+b //18 cout<<18 cout<<10 //因为10已经先入栈了 cout<<6//同上 上述实验的环境均为GCC4。5 据同学说VS2010执行的结果在DEBUG下和RELEASE下居然分别为:16 10 6 和18 10 6,不过我没有去验证过,有兴趣的同学可以去验证并分析一下。 附上一篇专门讲解C/C++表达式求值的文章。http://blog.csdn.net/luciferisnotsatan/article/details/6456696