今年要開始找工作了,本著積累經驗的目的,跑去做了下MTK的筆試題,筆試的內容主要是C++。
因為開發中一直使用C++,而且對C++裡的高級特性:面向對象,模板等都比較熟悉,還沒事喜歡研究下STL,BOOST,所以對自己的C++水平比較自信,因此事先也沒做任何准備,就直接去筆試了。本來筆試完了後覺得題目蠻簡單的,但是本著認真學習的態度回來後把題目都上機試驗了下,結果一下就悲劇了,錯的體無完服啊。。。
總結了一下:
1。認真對待,不要小看了筆試題目:做題的時候心想這些筆試題目都很簡單啊,很多題目都是掃了一眼就立即寫出了答案,結果回來後才發現這些題目都設置了陷阱,讓你掉進去就出不來了。
2。C++基礎不夠扎實。枉我還一天到晚的研究C++的高級特性,結果很多基礎的知識卻都是一知半解。
特將此次筆試的一些心得和體會記錄於此,好提醒自己。下面主要分析幾個我做錯的題目。題目並非與原題完全一致。
題目一:
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的析構
真相大白了。為什麼編譯器會這樣來編譯這個表達式呢?
下面2樓的夜風同學給出了正確答案。。為了不誤導後面的同學,特此編輯掉。。
上述實驗的環境均為GCC4。5 據同學說VS2010執行的結果在DEBUG下和RELEASE下居然分別為:16 10 6 和18 10 6,不過我沒有去驗證過,有興趣的同學可以去驗證並分析一下。
做這樣一道題還是讓我收獲很多,鞏固了C++的基礎。
今天就寫道這裡,後面有時間會陸續放出對其他“陷阱”題目的分析。
(未完待續)