題目一:
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