mtk 笔试总结

http://www.cppblog.com/ioriiod0/archive/2011/08/13/153284.html


做MTK笔试的总结(一)
今年要开始找工作了,本着积累经验的目的,跑去做了下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:" <                               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++的基础。
今天就写道这里,后面有时间会陆续放出对其他“陷阱”题目的分析。
(未完待续)

posted on 2011-08-13 17:30 江浸月 阅读(1787) 评论(19)   编辑  收藏 引用

评论:
#  re: 做MTK笔试的总结(一)--C++ 运算符优先级2011-08-13 19:50 | pansunyou
确实输出不同的结果:

[VS2008] cl.exe 15.00.21022.08 DEBUG输出16 10 6
[VS2008] cl.exe 15.00.21022.08 RELEASE输出18 10 6
[UNIX SCO] CC 3.1 09/28/99 DEBUG/RELEASE输出18 10 6
gcc version 4.1.2 20070115 DEBUG/RELEASE输出18 10 6
   回复   更多评论
  
#  re: 做MTK笔试的总结(一)--C++ 运算符优先级2011-08-13 21:00 | 夜风
<<在同一语句中连续使用,其实本质上是函数的复合调用
cout< 本质上是
operator<<(operator<<(operator<<(cout,a+b),a++),b++)
由于c函数参数传递顺序是从右至左,所以参数的计算次序是:
b++ //7
a++ //11
a+b //18
cout<<18
cout<<11 //应该是10,因为已经先入栈了
cout<<7 //应该是6   回复   更多评论
  
#  re: 做MTK笔试的总结(一)--C++ 运算符优先级2011-08-13 21:19 | right
尽管这种问题有确定的答案,但是实际上永远不要写这种代码。   回复   更多评论
  
#  re: 做MTK笔试的总结(一)--C++ 运算符优先级2011-08-13 21:47 | 江浸月
@夜风
原来如此,受教了。不过最后应该是
b++ //7
a++ //11
a+b //18
cout<<18
cout<<10
cout<<6
才对。   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-13 23:31 | 疯狂的面包
http://blog.csdn.net/luciferisnotsatan/article/details/6456696
我来给大家一个链接 很好解析这个问题   回复   更多评论
  
#  re: 做MTK笔试的总结(一)[未登录]2011-08-14 16:03 | a
题目也太水了吧。
第一题 就是 UB.
   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-14 19:04 | 俺不是坏人
未定义行为,结果多少都是正确的。   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-14 19:38 | 狂接
UB吧   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-14 21:34 | ccsdu2009
这样的题目 只能说蛋疼   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-15 09:38 | 各个
这种题纯粹就是坑爹的,出这种题的人就是一SB   回复   更多评论
  
#  re: 做MTK笔试的总结(一)[未登录]2011-08-15 12:39 | Chipset
可以看出出题的人根本不懂C/C++,这样的公司不去也罢。   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-15 22:58 | 夜风
@江浸月
哦,对的,10和6已经入栈了   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-15 23:07 | 夜风
@Chipset
不见的,有可能题目的用意在于考察是否理解<<操作符的函数形式,还有函数参数入栈顺序,如果这样理解,还是比较有技术含量的   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-15 23:13 | 夜风
@夜风
如果不理解,还真有可能出现大问题,我曾经就遇到过一个问题,后来看汇编代码时才回忆起<<的二元函数形式   回复   更多评论
  
#  re: 做MTK笔试的总结(一)2011-08-17 00:32 | 艹,蛋疼
在VC10上release才是16 10 6!






你可能感兴趣的:(mtk 笔试总结)