题目一:
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的析构
c++
真相大白了。为何编译器会这样来编译这个表达式呢? 函数
其实<<在同一语句中连续使用,其实本质上是函数的复合调用:
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