life02

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  197 随笔 :: 3 文章 :: 37 评论 :: 0 Trackbacks

#

void memcpy(void* pvTo, void* pvFrom, size_t size)
{
    
void* pbTo = (byte*)pvTo;
    
void* pbFrom = (byte*)pvFrom;
    ASSERT(pvTo 
!= NULL && pvFrom != NULL);
    ASSERT(pbTo
>=pbFrom+size || pbFrom>=pbTo+size);
    
while(size-->0)
        
*pbTo++ == *pbFrom++;
    
return(pvTo);
}
posted @ 2009-09-21 16:56 life02 阅读(205) | 评论 (0)编辑 收藏

 
http://bbs.sysu.edu.cn/bbscon?board=Job&file=M.1253356414.A&start=7681
最后说说面试吧。还是像以前一样,我会说一说大局一点的东西。现在面试官出的问
题千奇百怪,我一度为寻找正确答案而烦。我曾经在网上找了一篇《面试问题大全》,但 把里边的每一个问题都仔细回答。现在我仍然觉得这是必要的,因为如果不了解常问的问
题,你真的很难过面试关。但关键是,面试官的问题是千奇百怪的,你不可能准备那么多
问题,所以后来我发现这一招有它的极限,我觉得我们要做的,是以不变应万变。

  那么,怎么应万变呢?首先,我认为hr问你问题,并不是要你给他正确答案,而是要看
你的综合能力,比如说,你说话的风格,有的人说起话来让人觉得很亲切,有的人说起话
来却让人觉得有点冲;再比如,你的临场应变能力,当遇到不会的问题你怎么应对?再比如
,hr问你的问题是想了解你的优势。知道了这三点,我就想好了一些策略。

  一,面风问题。

    研一时,我和几个朋友一起去面试,内容很简单,就是一个自我介绍。但我发现我的
朋友的面风特别好,他在讲话时,咬字清晰,语速不急不缓,语调稳而不失活泼,特别是
,他的每一句话说完时,都会用降调,并做适当停顿。而我就不一样了,虽然也是同样几
句话,说起来语音不准,时慢时快,语调里还有一点要飞起来的的感觉。从那个时候起我
就开始注意台风好的主持人的节目,并开始模仿。这是我要说的第一点,面风问题。包括
你说话的风格,还有你的打扮,还有你的肢体语言,等等。
    另外要注意的就是,你要关注到所有面试官。李敖说过,他在做讲座时,要把头变成
摇头风扇,左吹一下,右吹一下。

  二、临场应变能力。

    我这人的临场发挥能力是很有限的,但我想出了一招挺好用的招式,叫“超级无敌拍
马笔记本”。方法如下:我事先准备了一本比较高档的笔记本。当hr问到你完全不会的问
题时,我就说:“不好意思,这一方面我暂时(注意,要说暂时)还不太了解,您能指点
我一下么?”一般来说,他会很高兴地向你吹水,这时,我就打开我的“超级无敌拍马笔
记本”,把他说的要点都记下来。hr这时很有做领导的感觉,我想应该爽得不得了。等他
说完了,我就说:“我总结一下,您的意思是***,是吗?”然后就把我笔记本里的每一要
点都说一下。最后我说:“我回去之后一定会好好了解这方面知识的,希望以后还有机会
进一步向您请教。”这样,我没有回答他的问题,而是把问题推给他,也化解了危机。当
然啦,这一招只有在万不得已时才用,如果他问你三个问题,你推给他三次,那麻烦就大
了。

    三,其实hr还是想通过问问题增加对你的了解。

    所以,当他暂时没有问题时,我可以说:“我有什么什么的经历,我能说一说么?”
这样你就有机会说出你的优势。另外,如果他问你一个问题,这个问题和你的优势无关,
但和你的优势间接相关,你也可以简要回答他的问题后,告诉他:“我还有一些话想与您
分享。”
记得,hr问你问题,并不是想了解你的答案,而是想通过引入一个话题来了解你。你 完全可以顺着他的问题引到你想表达的问题上。比如说:你有一个好经历A,又有一个比较
差的经历B。而hr偏偏问B不问A,那你就简要地说一下B,然后说:“其实这个问题,我还有 另外一件事可以分享”这样就引到你的优势里了。
    这样做的前提是,你要对你的简历和优点特别特别熟悉,他问一个问题,你要能立即
反映出你能从这个问题中表现出你的什么优点。

    这里还要回答一下之前有的同学的问题,就是说简历写成那样,怕不怕露馅。首先,
你写的每一点,都没有说谎,所以你应该底气足。另外更重要的是,有些东西是你无中生
有的,这些东西你就要加以关注,尽量地想象你可能处理的细节,并且天天想,天天想,
想得久了,假的也就成真的了。我承认我的简历有一部分是假的,不过后来我毫不怀疑我
有那样的经历了。

    面试就写到这里吧,这个系列也写得差不多了。我看到群里有人说我写文章是给师弟师妹传点经验,其实这太
抬高我了,也有的人说我在show,这个观点好像也不是很对。我就老实招了吧,这一周我女友的工作比较忙,我又
刚看完了我想看的书,所以一个人很无聊,就乱写东西了。我自个没有账号,因为我很少上bbs,所以才借了maomi
的账号。这就是我写文章的最主要原因,呵呵。

    最后再强调一下,我写文章是因为好玩,写过就忘记了,也没心思去检查。所以如果我有些话说得太绝对太片
面了,有可能是我的想法真的太绝对太片面,也有可能是我没表达好,也可能是你没理解好。总之,写文章是一件
好玩的事,我们不要太认真去对待它。大概知道我要说的是什么就行了,没有必要一句一句地看和想,那样你看起
来也很累。

    最后,祝下一届的师弟师妹们找到适合自己的工作,也希望过来人多来bbs上灌灌水,让后来人少走一点弯路。


    希望我的两年真能借给你。再见^-^
posted @ 2009-09-20 09:46 life02 阅读(246) | 评论 (0)编辑 收藏

http://bbs.sysu.edu.cn/bbscon?board=Job&file=M.1253281471.A&start=7585
 昨天说到如何把简历写得让人觉得很牛。现在回顾一下:把你经历过的事,分成一步
一步,然后用hr喜欢看的语言描述出来。至于你能写得多好,完全看你的努力,我举的那
个例子,只是随便写出来而已,只要你用心,你完全可以写得比例子好得多。

 
  现在说一说排版的问题。这是很重要的,但比较少人重视。特别是有些马大哈,别说排
版排得好看了,写出来的简历n多错别字,这种态度当然是要不得的。

hr在看简历,就如皇帝在选妃子,这一点之前已经说过了。所以你写出来的简历,必须 给他耳目一新的感觉。这是一个大局观,就好像之前说的要通过行动实践去了解自己适合
什么一样,我认为是很重要的,只有理解了这一点,才有以下的各种技巧。

  一、除了一些硬性要求(如学历)外,hr更多的是直接看你的简历有没有亮点,而不是
事先设定一些亮点,再看你有没有这些亮点。所以你只要提供对你有利的信息,而没有义
务让hr真正了解你。这样说有点抽象,我举个例子。比如说,如果你是团员,你就不必在
简历上写上。为什么呢?你从周围随便抓一个人出来,不是党员,就是团员,所以如果你
是党员的话可以写一写,但如果写你是团员的话,等于在告诉hr:我不是党员。从hr的角
度上看,他在看你的简历时,并不会刻意去找你的政治面貌,所以如果你是团员,只要你
不写,他就不知道你的政治觉悟不高。(这里假设党员比团员好,但这个假设不一定成立
)再举一个例子,如果你本科是从一个不知名的院校读书的,那么你就尽量淡化这一点。
比如说,你在本科自学了一些课程,获得了演讲比赛一等奖,当了学生会部长,这些都可
以算作在中大的经历(他哪有兴趣查你自学的课程是本科时学的还是研究生时学的啊?)
你可以在中大名下安很多亮点,而对本科毕业院校一笔带过。

  二、hr在看你的简历时,并不像我们在读教科书一样,从前言读起,再读正文,再读后
记。往往他是随机看你简历上的任何一个角落。这是很重要的,因为有的同学为了凑字数
,写了一些亮点之后,又写了一些不亮的。这就好比你家换了新房,买了名沙发名电视名
家私,却按了一个破门一样。hr看到你的破门,他还会推开门去看你的豪宅么?所以,你
写出来的每一点,不能差别太大(注意,他的第一眼可能落在简历的任何一个地方)

  三、虽然这样说会让一部分人生气,但不可否认的是如果你皮肤太黑,皇帝一定不会选你的。所以,简历要尽量
显得清秀白净一点。特别是,不要将大面积的文字设置着灰色背景,虽然这样从电脑上看起来挺好看,但一旦打印
出来就显得很黑。还有,在使用项目符号,尽量用空心的符号,不要用实心的。

  四、最重要的,要对齐,对齐了,才能令hr耳目一新。这是一个大话题,可能要花比较多的时间来说明。

(1)语式上的对齐。以下两句话就没有对齐:

   搜集资料,撰写策划书。
   对数据进行分析比较,得出结论。

  要改为:

    搜集资料,撰写策划书。
    分析比较数据,得出结论。

(2)格式上的对齐。以下两句话也没有对齐,因为第一句最后有句号,第二句没有

    搜集资料,撰写策划书。
    对数据进行分析比较,得出结论

(3)表达方式上的对齐。这一点很少人用到。中文是很奇妙的,任何意思都可以概括为一个四字词语,而这是一种
很美的对齐方式。例如:

    搜集资料:通过各种渠道收集二十多家公司的相关资料。
    分析数据:对收集到的资料进行比较。

(4)排版上的对齐。比如说,在写每一个要点之前,先写时间,因为时间的格式都是YYYY-MM--DD,这也是一种很美
的对齐。

下面提供一个模板,仅供参考:













2007-09 --2009-07           中山大学            生科院              硕士
2003-09 --2007-07           华南理工大学        信科院              学士

2003-09 --2004-10           信科院学生会        宣传部            副部长
   搜集资料:通过各种渠道收集二十多家公司的相关资料。
   分析数据:对收集到的资料进行比较。
   搜集资料:通过各种渠道收集二十多家公司的相关资料。
   分析数据:对收集到的资料进行比较。

2007-09 --2008-09           生科院学生会        组织部            副部长
   搜集资料:通过各种渠道收集二十多家公司的相关资料。
   分析数据:对收集到的资料进行比较。
   搜集资料:通过各种渠道收集二十多家公司的相关资料。
   分析数据:对收集到的资料进行比较。








  上面这个模板,四个时间都是对齐的,中山大学、华南理工大学、信科院学生会、生科院学生会也是对齐的,生
科院、信科院、宣传部、组织部也是对齐的,硕士、学士、副部长也是对齐的。你还会看到,有一列四字词语也是
对齐的,而且其后的冒号也是对齐的。

  有关简历问题就写到这里了。我是按照以上的要点写简历的,我从大四下学期开始写,一直写到去年十一月,中
间摸索了很长一段时间。自从我完成这份简历之后,我所投的纸质简历都能进面试(去年十月到十一月期间我还没
最终完成我的简历,但我也投了不少公司,中的机率挺大的,但还有不少不中)。当然,这部分是因为到了十一月
,牛人们都不怎么找工了,我才这么幸运。而且我找到工之后就没再投了,如果当时再投下去,可能就没有这么良
好的记录了,呵呵。




posted @ 2009-09-20 09:40 life02 阅读(237) | 评论 (0)编辑 收藏

http://bbs.sysu.edu.cn/bbscon?board=Job&file=M.1253201539.A&start=7459 
下面说一说写简历的技巧。关于写简历,网上有很多很多资料,所以我不想很系统地从
头讲起,很多司空见惯的问题,比如简历要写在一页纸之类的,我就不再重复了。另外,
很大程度上我是在教你怎么把牛吹得又大又合理,这就好像会计处理上的合理避税一个道
理,是在不违法,也不违反道德的基础上进行的,所以不要说我在教你说谎。如果我教你
说谎,就等于会计上偷税漏税了,注意,我只教你合理避税,而不教你去坐牢。

  很明显,找工就是一个皇帝选妃子的过程。在你没有牛offer之前,企业就是皇帝,他可
以左玩你右玩你,然后把你贬得一无是处。但当你有了牛offer之后,你也可以到面试现场
上大闹一场,甚至对着hr好好骂一场,这个时候,你是皇帝,而他是妃子。不过,在你成
为皇帝之前,你总要当一回妃子,直到你拿了牛offer当了皇帝,所以,在写简历时,我们
必须把自己当成妃子,想一想怎样让皇帝选中。

   被皇帝选中的妃子,我想一定具有以下优点:

    一、能歌善舞,琴棋书画样样精通。
    二、长得靓,身材好,又会打扮。

   所以,写简历时,我们的目的是:

    一、简历的内容要充实,显得很牛。
    二、要十分注重排版。

    很多同学都知道要把简历写得很牛,却不知怎么牛起来,因为他说他没有什么好经历
。而有相当大一部分同学根本就没有注重排版。下面就从这两点入手,谈一谈我的一些想
法。

    所谓巧妇难为无米之炊,如果你的社会经历很少,怎么办呢?那么假设,你班里要组
织一个活动,班长让你去买水,以便在活动现场用,你会怎么做呢?或者,小时候你老妈
让你去买瓶酱油,你会怎么办?我想你的社会经历就算少,买水买酱油应该还是做过吧?
那么现在我们开始写一写,就以买水为例。

    step1: 我找了几个经常去happy的人,问他们学校附近哪里有卖水(这里假设你连在
哪买都不清楚),他们告诉我,小北门、东门、小西门,多品美,教育超市都有卖水。我
马上上网查了查,发现东门和小西门太远了,多品美和教育超市因为在校内,所以价格比
较贵,所以决定去小北门看一看。

    step2: 用手机短信通知各位同学,问他们要喝什么水,并统计一下数据:有30人想喝
可乐,另外15人想喝橙汁。

    step3: 我算了一下,大概要100元经费,于是向我们班的生活委员要了钱。

    step4: 我翻山越岭,拔山涉水啊,终于来到了小北门,发现这里有三家店有卖水,于
是分别问了问价格,发现其中美宜佳的可乐和橙汁打折打得最多,于是我决定从美宜佳那
时买水。

    step5:我和老板讨价还价,最后定下价格。但他不帮我送到宿舍里去,我只好打电话
让我几个哥们过来帮我搬东西,好不容易啊,我们几个齐心协力把水搬完了。

    step6:由于水是打折的,所以我只用42元就买了所需要的水,还余下8元,我把这些
账认真地记下,并把账单和余下的8元交给生活委员。

    step7:活动当天,我把水分给需要的同学,他们喝完之后觉得很满意。我问他们说,
你们觉得我有什么地方值得改进的呢?他们说:要是能免费提供就好了。我:¥#@¥#%¥
%

    好,我相信任何中大人都能写出我以上写的像小学生一样的文章,现在我们把每一点
都用hr喜欢听喜欢看的句子表达出来,上面7点变成了:

    step1: 搜索并比较数据,起草策划书并成功立项。

    step2: 利用大版,传单等宣传方式对项目进行宣传。进行需求分析,统计并比较数据
,搜索并整理相关资料,拟定策划书。

    step3:预算资金,成功申请项目经费。

    step4: 进行实地调研,进行数据分析,根据成本最小化原则确定解决方案。

    step5: 协调团队成员,促进团队合作,保证物资运输和供应。

    step6:负责财务管理,记录相关明细,保证资金顺利运转。

    step7: 收集反馈信息,总结经验。

    好了,你会发现,以上7点,无论你参加什么活动,都可以套下去。我是理工科背景的
,所以我的吹水能力绝没有文科生那么牛,所以我相信你一定能写出更多step,并把它用
hr喜欢听喜欢看的句子表达出来。好了,如果你觉得你没社会经历,那现在就去小北门买
水吧!(要注意,如果你没有去买水,就不能这样写哦~~我们是不能骗人的,只要你去买
水,你就做了以上七点,这样你才能在简历上光明正大地写上这7点)

  以上只谈到如何让你的简历写得很牛。至于简历的排版,以及这样做会不会露馅,下次
再说吧,我睡觉了。。。。。
posted @ 2009-09-20 09:39 life02 阅读(228) | 评论 (0)编辑 收藏

http://bbs.yingjiesheng.com/thread-15033-1-1.html
今天应该是毕业找工作生涯的最后一次面试了,发个笔经面经,为后来人
铺路.我面的是Radio Network Planning。
笔试:海选,通过chinahr出的一组能力测试题筛选。好像筛了不少人。
题目包括词语填空,阅读理解,图形,数字题,基本数学题,表格题。
一面:面试官为应聘职位的部门经理。基本上为中文,中间可能抓住项目的
某个部分突击一下英文。面试官很和蔼,不用紧张。
问的内容涉及:个人介绍,项目介绍,然后抓住关心的项目问细节问题。
做过的项目很match的话,问的会更详细一些。然后问,项目中碰到的最
大困难是什么?怎么应对的?优势,缺点,举例说明一下?三个词形容
一下自己。然后,被面者问面试官问题。
二面:二面是nokia请专业人员做的人力测评,大概要多半天的时间。主要看个
人特点和潜力。改专业人员会把测评结果提交给部门经理,辅助经理做
决定。网上有比较多的面经,讲的也很详细。流程大致如下:
1)7个人小组活动:构建一个太空站的项目,给了太空站的地图和项目介绍,要求
说服董事会投资和盈利。黑板上写好了每个人的拼音名字,所以也没有进行个人介
绍,然后hr用英文介绍了一下我们下面project主要的任务,给了10分钟的时间想,并且
期间可以提问。然后30分钟时间group讨论和实现。在整个过程中一半中文,一半英文。
这个时候会有人记录你的表现,后来我知道他们不是要你表现的最优秀,但是要有grou
p spirit,能够接受他人的意见和提出自己的见解。讨论结束以后,group可以任意方式
做中英文综述,接着hr会要求你给给自己打一个分数,然后问你为什么这样打分。
2)逻辑能力测评:24道图形题,15分钟做完。
3)午饭。
4)性格测试:300多道题,对一句话的描述回答true or false。
5)一组问卷:你的优点缺点,职业规划,等
6)Interview:问了我是否有看到网上的面经,有什么帮助?
刚才的表现中为什么会想到哪些?
自己选一个项目说明自己是怎么工作的?由于我说的那个项目中我是项目 某小组的组长,就问到我是如何带领团队工作的?这个问了比较多。
你的职业规划是怎么样的?
提问。
7)Over。
本贴地址:http://bbs.yingjiesheng.com/thread-15033-1-1.html

笔试:
  电路,自控,机械,net,c#,结构表,英文翻译……
  这还不算啥,最后一页才搞笑。
  请书写无机和有机化学方程式各一个。
  牛顿三大定律,热力学三大定律
  ……
  面试:
  job hunting(2)之NokiA  Nokia一直是很牛b的,从9月开始就收简历,折腾到了12月,历时2个半月之久。
  第一次收到电话面试,正在上班,觉得十分尴尬,跑到外面在门卫面前表现了半个小时的英语,估计他都以为我有病,话都说不明白。
  实现一点没有准备,就被Nokia给突击了,事后我一直想,简历一定要做好,绝不能再犯类似错误,我竟然写了C++项目经验比C时间还长,让面试的gg抓住了不放,非要问个一二三。
  还是庆幸那段时间还在看friends,对英语的基本感觉还在,没有生疏,顺利通过了电话面试。接下来的技术笔试,复试,都没有悬念的通过了,nokia还是比较正式的,就是战线拉的太长了,后来因为签了其它公司,就没有参加最后一次hr面试。
  一直以来,我在bbs上是属于潜水者一型的,接到nokia的offer也有一段时间了。忽然就很有点感触。很想写出来和大家分享一下我的面试,希望能够给下一届的同学们一点参考。前面也有一些关于nokia面试的文章,我看了一下,和我的面试情况基本相同。我就不重复说了,把我在面试中觉得应该注意的地方写一下吧。
  1,第一面的时候主要是考你的base knowledge,笔试完三页纸的技术问题以后(我当时考的主要是基本的通讯知识和GSM的基本概念),部门的manager就会问你一些技术问题,如果你有项目经验的话,也会大概问一些,但是没有深入(这个很重要,其实他在第一面以后就会对你的个人经历有一个初步认识,以后的面试也是基本上围绕这些问题展开。)整个过程很轻松,大概面试30分钟左右,然后他会通知你回去等消息。
  2,老实说来,我就经过两次面试就接到录用通知了,因为nokia的第二次面试安排的很紧凑,基本上是整整一天。第二次面试我是到异地去面试的,nokia之类的外企如果通知你去外地面试是一定会报销路费和三星级以上(nokia指定)酒店的住宿费的。等我到了公司以后,发现我们是安排一个group一起面试的。当时我们那个group是6个人,听说也有8个的。等大家到齐了,我们被安排到一个小房间做一个“构建动物园”的project,这个project还蛮重要的,hr,部门manager和老总(一个荷兰老外,很象圣诞老人)都来了,黑板上写好了每个人的拼音名字,所以也没有进行个人介绍,然后hr用英文介绍了一下我们下面project主要的任务,给了5分钟的时间想,然后15分钟时间group讨论和实现。在整个过程中可以用中文,这个时候会有人记录你的表现,后来我知道他们不是要你表现的最优秀,但是要有group spirit,能够接受他人的意见和提出自己的见解。
  讨论结束以后,group推荐一个人出来做中英文综述,当时我们组是推荐了一个女生讲的,都是她一个人讲(呵呵,后来听别的组说他们是推荐一个人用英文,一个人用中文),我当时忽然很胆怯,事实上英语也没有那么牛,所以基本上没有说什么。接着hr会要求你给整个group打出一个分数,给自己打一个分数,然后说你为什么这样打分。我们那组出了一个意外,第一个站起来回答的dd居然给每个人都打了分数,我在极度惊讶之下,也飞快的给每个人打了分数。后来问到我时,我说了我的分数,我给自己打的分数比group分数高,事实上只有我一个人这样打了,hr很奇怪的问我,为什么我觉得自己的表现很好?
  我当时特别的窘迫,想了一下我说我觉得自己能够积极主动的说出自己的想法,能够接纳他人的建议,而且给group打分和给自己打分不是基于同一个评判标准的。所以建议ddmm们以后如果要打分一定要想好为什么要给自己打这样的分数。基本上,nokia的面试官都会特别的客气,不会咄咄逼人,但是如果你自己要准确的给自己定一个位。现在想起来还是觉得当时好丢人阿。。。。。后来我们很惊讶的发现,那个表现最好的mm没有录取,很可惜,不过这也能够看出来,nokia不是要求你能够表现多出色,它要的合适的人,所以面试的时候不要有压力,如果是你的,一定会是你的。
  3,午餐,nokia请客,好丰盛的KFC大餐,不过大家好像都没有什么胃口,大家都在相互聊天和分享公司信息。
  4,下午的时候就发了一堆的考卷,有365题的人格测试题,好像是要划出一个曲线看看和公司要求的人才符合不符合,总之你要尽量表现得乐观就对了,他们很看重这个。那个人格测试题,特别的搞笑,还有造句题,for example,我认为女人——————————。我当时的答案是我认为女人应该独立自主。大家的答案五花八门,什么我认为女人能顶半边天。女人应该靠自己。。。。。还有50题的智力测试。(就是那种几个图形,要你选择最相近的一个之类的)。我是乱来一气,我一直以来都不知道这个到底是怎么回事,都是直觉。同步进行的是hr面试,一个一个的叫出去,大概每个40分钟左右。
  5,终于轮到我面试了。进门前,我没有敲门,直接开门进去了,说了一声下午好,面试我的是hr和一个部门的manager,在整个面试期间我觉得最好的就是他们很尊重你,他们对你的情况特别清楚,好像就是和老朋友聊天一样。其中重点就是问了我的项目经历,因为我有专利,他们特别问了我对自己专利所有权的看法,问我为什么基本上由我完成的项目,老板做第一专利人?
  我说其实这个构思是老板的,虽然具体实施由我个人完成,但是指导工作和申请都是老板完成的。而且由其他的师兄弟也能够完成,具体会找我来做是因为当时我自己提早学习了工具,所以老板觉得我来搞比较合适。他们开玩笑说是不是你比较聪明?我说:其实能够读到这个程度大家应该都差不多,我觉得自己属于比较勤奋。他们好像很满意,问了我对薪水的要求。我知道他们是准备要我了。
  我问他们根据这几轮的面试他们觉得我应该拿怎么样一个薪水比较正常?他们说基本上他们会尊重个人的意愿,当然是在不会太离谱的条件下。我当时开的不高,他们给的也属于我开的范围里面。从这点可以看出,如果你个人比较牛,那么你不妨开出自己比较中意的工资。如果他们能够给,他们基本上不会太拒绝。现在想来,当时真的开的亏了。
  面试完以后,他们告诉我2个星期之内会给你答复。后来想想这个面试很重要,基本上要人也是这个环节,其他环节都是参考。问的东西特别的细,最好不要骗人,如果你是撒谎的话,hr会一步一步的问出来的。还会问一些你和他人相处的事情,不会直接问,他会一点一点的追问,在回答每个问题之前不要太紧张开口,想想在说,说话不要太快,直视他们的眼睛有助于消除紧张并且给人一种自信的感觉。
  大概6天以后,他们给了我答复,希望我能够加入他们公司。。。。
  算来从第一次面试到给offer经历了大概1个月的时间。自己的求职也算是落下了帏幕,虽然还有一家公司开的待遇比nokia高,但是我希望感受一下nokia的氛围,所以还是决定把自己卖了。感谢gg在我求职期间给我的帮助和鼓励。
  在整个求职期间,我可能本身不是特别着急,所以心态很好,大概会有一定的帮助吧。还有在求职的时候,女生化一点淡妆真的很必要,这样给人比较职业的感觉,虽然不一定要穿职业装,但是一定要穿得得体大方。
  最后祝福大家都能够找到理想中的工作,也希望我的求职经历给大家一点帮助。
本文来自面经网-求职就业好帮手,原文地址:http://www.51mianjing.cn

 

posted @ 2009-09-16 17:38 life02 阅读(502) | 评论 (0)编辑 收藏

 1#include <iostream>
 2using namespace std;
 3
 4typedef struct LNode{
 5    int data;
 6    struct LNode* next;
 7}
Linklist;
 8
 9void disList(Linklist* L){
10    Linklist* p=L->next;
11    while(p!=NULL){
12        cout<<p->data<<" ";
13        p=p->next;
14    }

15    cout<<endl;
16}

17
18void creatList(Linklist *&L,int* a,int n){
19
20    Linklist* s;
21    int i;
22    L=(Linklist*)malloc(sizeof(Linklist));
23    L->next=NULL;
24    for (i=0;i<n;i++)
25    {
26        s=(Linklist*)malloc(sizeof(Linklist));
27        s->data=a[i];
28        s->next=L->next;
29        L->next=s;
30    }

31}

32
33
34void sort_list(Linklist *&head){
35    Linklist *p=head->next,*q,*r;
36    if (p!=NULL)
37    {
38        r=p->next;
39        p->next=NULL;
40        p=r;
41        while(p!=NULL){
42            r=p->next;
43            q=head;
44            while(q->next!=NULL && q->next->data<p->data)
45                q=q->next;
46            p->next=q->next;
47            q->next=p;
48            p=r;
49        }

50    }

51}

52
53int main(){
54    Linklist* L;
55    L=(Linklist*)malloc(sizeof(Linklist));
56    int a[8]={3,34,5,4,32,39,1,0};
57    creatList(L,a,8);
58    sort_list(L);
59    disList(L);
60}
posted @ 2009-09-15 21:26 life02 阅读(596) | 评论 (0)编辑 收藏

 1template<typename T>
 2void sort_shell(T* a){
 3    int d;
 4    int i;
 5    int j;
 6    T temp;
 7    d=N/2;
 8    while(d>0){
 9        for (i=0;i<N-d;i++)
10        {
11            j=i+d;
12            temp=a[j];
13            while((j-d)>=0 && temp<a[j-d]){
14                a[j]=a[j-d];
15                j-=d;
16            }

17            a[j]=temp;
18            
19        }

20        d=d/2;
21    }

22}
posted @ 2009-09-14 20:31 life02 阅读(205) | 评论 (0)编辑 收藏

嵌入式方面的试题

预处理器(Preprocessor)0 n# S1 W+ C8 m. b
$ ~6 M$ \& T2 K* U& Z! |" I  o
1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
2 \& |+ t, D; d3 \, H          #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL0 y" |2 O4 C1 i0 P: `! I0 f
我在这想看到几件事情:* J6 ?8 U6 l! A8 N
1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)) m4 M1 _  [( t6 w
2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
4 N7 R& k+ g1 u" t 3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
: @% a- C& `7 `) e& d5 b) O9 J 4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。" b' k% ^7 |- Q% l1 L! k/ t$ G
+ I2 ^. l! A1 X+ F
2 . 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。: M% ~% I- @5 D' O2 ~/ \7 I
         #define MIN(A,B) ((A) <= (B) ? (A) : (B)) / ?" [) s/ _, R! q$ E, b8 i9 p
这个测试是为下面的目的而设的:
7 N% M5 O6 D' G  k8 h5 i& P/ {+ U 1) 标识#define在宏中应用的基本知识。这是很重要的。因为在  嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
* E  X9 T! O) _/ f' { 2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。
2 k# n  w. p0 _+ G: C 3) 懂得在宏中小心地把参数用括号括起来$ [8 c4 M+ E& x2 q* K2 r9 @
4) 我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?
' a( N* C! B* K         least = MIN(*p++, b);
! a8 Q5 g+ e9 O* L' {! l6 i # `1 c# ^* Z7 Y6 u# z
3. 预处理器标识#error的目的是什么?! m/ @2 _, y8 u/ t- o
如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。4 C4 }5 v- ~7 o. i! e

4 b6 D6 d7 @% z  z3 Y   V0 o1 W9 D! `- B
死循环(Infinite loops)
7 ?7 k2 s1 {$ }0 j! _. B
' N8 j9 M: v) t' ?1 p 4. 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?
# h# \1 M0 u( |  @" _ 这个问题用几个解决方案。我首选的方案是:
+ K1 w* ]3 [% c / s4 f+ \% ^. H8 o4 @7 I! q
while(1)5 |- V$ D0 \) {% c+ x( C: R
{$ S& G( }8 |' Q6 D. L% B: m3 K

. v/ A, B% r4 ?5 w8 y7 j4 H2 Q }
& x" d; o+ ]+ C6 l; z1 I
6 X" A- Q, Z" U, J, e0 F0 E+ J 一些程序员更喜欢如下方案:
4 d; p9 [1 w. u) v5 U' H3 g
/ Y. M& [6 ?' Z- H6 U8 a& A* ~ for(;;)3 Q, h( y' z2 I+ `# X& n, Q
{! f& [; F! b: ^( ~# A4 {
5 J9 i" H0 s( q  K
}" k$ n3 S- [! ?7 i1 E5 @/ x6 h
0 i" R, S, m9 t: T
这个实现方式让我为难,因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的基本原理。如果他们的基本答案是:"我被教着这样做,但从没有想到过为什么。"这会给我留下一个坏印象。
% U. y5 J6 Y5 N* T4 q
5 F/ Q& W" b; K" n: j) m' x 第三个方案是用 goto
1 N. g) K( P" P/ ] Loop:
' N! F0 q+ ~6 h' }) g2 m% Q+ A ..., Z3 T5 ~0 A5 W0 F" _
goto Loop;
" Q' K4 A1 o1 L2 J/ P/ k8 Y 应试者如给出上面的方案,这说明或者他是一个汇编语言程序员(这也许是好事)或者他是一个想进入新领域的BASIC/FORTRAN程序员。! j$ y$ |+ c2 |# A1 D; Q! o

: p* z7 ^; w; H " Q; O; a+ ~7 P# i* n* d
数据声明(Data declarations) ( E- V# z, ?* o5 \

( \+ V: N0 ]5 f2 t4 C6 B 5. 用变量a给出下面的定义
% v  h+ a9 j4 L  H9 g a) 一个整型数(An integer)   K5 A# B& x0 o9 h+ M) J- V
b)一个指向整型数的指针( A pointer to an integer) # u, d6 X6 Z1 P) \" E( d: l
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r : X" L" _' Q: w/ w  n4 f9 D
d)一个有10个整型数的数组( An array of 10 integers)
9 C6 z+ X9 _7 H1 L1 G e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
; y- j) S- q4 C4 ^6 s6 t% o/ t2 u5 n; N0 x f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
+ c- L& d8 I1 E& ^6 J$ g% ] g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
  v5 t. D. [6 ]4 Y2 n h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer ). s, k( g& l9 g; _0 M. f
: @4 t6 M8 o$ J3 t
答案是: 5 N* N) C% t2 x7 K% x* e2 N; n5 ~
a) int a; // An integer # z: B& D4 [7 Y! ]6 Q
b) int *a; // A pointer to an integer 4 x' Z- A0 z8 U
c) int **a; // A pointer to a pointer to an integer 6 q, A9 R2 \4 j) x
d) int a[10]; // An array of 10 integers 5 q5 m4 ?8 E: Y% i0 E; V
e) int *a[10]; // An array of 10 pointers to integers 0 G: \% S1 ~1 q( S& W; n
f) int (*a)[10]; // A pointer to an array of 10 integers
1 z" i! t) A5 I% o/ y g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer 3 R8 }4 |3 A- F" x% r) D% q3 a
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer 8 b. {' F5 p% [' l

; H$ H6 f( `5 ^& X 人们经常声称这里有几个问题是那种要翻一下书才能回答的问题,我同意这种说法。当我写这篇文章时,为了确定语法的正确性,我的确查了一下书。但是当我被面试的时候,我期望被问到这个问题(或者相近的问题)。因为在被面试的这段时间里,我确定我知道这个问题的答案。应试者如果不知道所有的答案(或至少大部分答案),那么也就没有为这次面试做准备,如果该面试者没有为这次面试做准备,那么他又能为什么出准备呢?
) Z2 ?& ]3 X. A6 b7 L' p( i3 v% X % t/ S/ s! E7 ~8 I) ?9 U
Static 2 s9 \  b3 h. R* b, h

9 K3 i$ L# Z% m 6. 关键字static的作用是什么?% v( y) E: E- B$ z, s
这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:5 m: B! t+ Z; n" b. W. b9 w5 m2 r# R. M
1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
% U9 O- |% ^4 T- p0 o: u6 h; M$ W 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
1 }* @% k* h8 u( `/ d& p 3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
5 E8 W. a5 ~& J) W" r/ O . Q. R; N, U$ i5 W. r
大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。( y; w5 p) \& {; x9 H/ O

/ p- u' L1 s( @! O) u# g5 w* T
; @( s; R/ k7 Y6 x/ |( C1 ?! ` Const
% y9 O* t# P8 y  H4 v
; m% |0 Z7 ^$ z! x 7.关键字const有什么含意?" d3 f* M, k% z& n$ c
我只要一听到被面试者说:"const意味着常数",我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着"只读"就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)5 H5 [: G" L0 B* W
如果应试者能正确回答这个问题,我将问他一个附加的问题:4 G' S" F" b) K# s* U
下面的声明都是什么意思?, O, O$ w( d" V
3 Z2 U* n* L7 Y$ c( ]# B
const int a;8 |6 `& m6 U. N* G7 p5 P; S
int const a;
' c: B: P  ]! N1 ]6 Z const int *a;
% v+ m; y) e& o int * const a;
% z- O: Y  g: R8 `( y  {: y5 x int const * a const;, W+ i& r. Z9 {) l
; O+ l% H9 ]  ]& S0 {" Q* ^
/******/3 J& @% |, Q* W1 C( u
前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:. O. E& ^- b5 ?+ K( S
1) 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。), m% \  J  X; P! A; W: x
2) 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。. v& H1 I' T: V) c9 W% f. i1 S
3) 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。2 l0 Y* t9 F& W7 Y( ^7 e. p( L6 c

8 ^: d# D$ h5 i) c; q ; D% o$ b/ t5 D
Volatile
5 X# }4 M" s- p  l2 [ . S% ^/ c* w; U4 I" x/ ], C6 A
8. 关键字volatile有什么含意?并给出三个不同的例子。
8 [/ ~, Z* p" w# f5 [! h1 t 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:: h9 R) A( |* k
1) 并行设备的硬件寄存器(如:状态寄存器)' G+ m$ p! Y5 D6 l  v' A% C
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)7 [5 A6 E& G  U1 ]9 P" z# }
3) 多线程应用中被几个任务共享的变量% V$ ?& X: v8 c) T" M% ?
" o) R% y+ i3 h/ l5 a) u2 L
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。
- g+ D  V1 E# z$ z4 b 假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。! K! H; b' ?, x
1)一个参数既可以是const还可以是volatile吗?解释为什么。
& {' o0 r! D& B/ q: T* m1 q 2); 一个指针可以是volatile 吗?解释为什么。
3 a$ j4 M! \4 E% Q. U& F/ C: | 3); 下面的函数有什么错误:* k; n; ?, O7 U" C+ V1 r
( V, Y' Y% e1 D8 R) T5 w1 b* W
int square(volatile int *ptr)
2 R9 N: B- O& s! p {
# o& o- s- _) C* ]8 `         return *ptr * *ptr;
% Q5 H2 q2 }: h9 C- @( _% | }$ L6 P- o( J, n: Q
1 r5 f& R" {& _$ X# |0 U
下面是答案:
+ e# T" h3 h0 d' L 1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
8 b& [  N$ ^1 _5 l' ], P 2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。& {% J3 F3 N, M0 }# \3 h
3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:  |- k3 U! M2 f( ?6 v' _

8 B- n, K+ x* V  s2 o int square(volatile int *ptr)
# b8 B& F( e; B0 Y, _3 f {8 U. g1 p" H5 Q' O# Z- M- @, u
     int a,b;
; O2 Q; C% S& Z8 }. Q' @     a = *ptr;, f2 V5 ^1 X% u1 Q0 I
     b = *ptr;" D4 B4 @% W: N, x
     return a * b;; b( n0 O* M" m
}' x* U. _' U1 i4 q$ \# D
" l: H9 f$ P1 l6 W! Z$ P. b9 M- b
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
& y) ^2 ], [" E9 A7 i# N$ F* ? ) ^, t' Q+ Y. u2 T8 g
long square(volatile int *ptr)
/ I  N5 m$ l1 X {9 Y) I/ i. S1 s( {3 u6 c8 R4 F
     int a;
- L/ w( `% i" z; [+ B0 }     a = *ptr;" Y9 B4 S6 ?: W7 T1 ]
     return a * a;
7 w: x3 j: o; T4 V! m }+ s* Z/ v/ H/ m% G

6 g+ X7 F2 q' P3 Q* `, S 位操作(Bit manipulation)
, E$ w' G- @: {" y ( n5 j, v0 N+ d% E2 h  ^+ u+ V
9. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。% j5 n+ |' `# d
对这个问题有三种基本的反应
( ~5 g( @9 ~! i9 q. T. L, { 1)不知道如何下手。该被面者从没做过任何嵌入式系统的工作。
* C. Z4 ]' ^+ @. @. R1 S# y8 g 2) 用bit fields。Bit fields是被扔到C语言死角的东西,它保证你的代码在不同编译器之间是不可移植的,同时也保证了的你的代码是不可重用的。我最近不幸看到 Infineon为其较复杂的通信芯片写的驱动程序,它用到了bit fields因此完全对我无用,因为我的编译器用其它的方式来实现bit fields的。从道德讲:永远不要让一个非嵌入式的家伙粘实际硬件的边。
% g+ w- L* s, X( C  V 3) 用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法,是应该被用到的方法。最佳的解决方案如下:) Q" a2 Q" S) T4 ?

1 F" I; a1 k8 _8 W8 H #define BIT3 (0x1 << 3)6 [2 L5 C! D" o5 }3 y/ ?
static int a;
+ b& Q! b+ ]2 b  Y& _1 B
  m8 j/ i  r+ a) O void set_bit3(void) 3 O) C, i; z# g: p3 O: W
{0 c/ p8 J" Z7 G$ b
     a |= BIT3;
' L6 f# V. b5 A5 u7 T }$ r( S) t: s$ F4 \- X+ m  o1 v
void clear_bit3(void)
% b' S5 Y3 |' r7 a {/ N! ]9 c0 r& V9 X1 E- V( z
     a &= ~BIT3;# q$ I  n, J9 l8 ~& F" p) G
}4 D1 L2 V" n+ K' ]2 [8 ~& C

/ e2 M- e* W. s 一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数,这也是可以接受的。我希望看到几个要点:说明常数、|=和&=~操作。6 x, j7 r  i8 b& [0 q' n( K

% i+ D, I4 g# S& V6 ~6 p6 [8 @  Z 4 s1 A+ G$ |) A" f) v% v
访问固定的内存位置(Accessing fixed memory locations) , K) U' H4 T8 I* i0 ~
% @: _- ^, N# r4 R" z5 ^
10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
  z) n9 w3 b% N! Q( V 这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下:7 g3 {/ f1 N9 A
     int *ptr;
/ f6 {& ~" _) L$ g* {1 ]     ptr = (int *)0x67a9;
1 f3 m5 S4 g$ U, P     *ptr = 0xaa55;8 W0 U4 m( F, `
- C2 I' G5 T; ?9 D3 m
  A more obscure approach is:   r# a4 R6 L) r. A& [
一个较晦涩的方法是:
) K& s! X9 h; g. |& p7 q1 U & j0 D( k4 s$ G" w3 D1 E1 L$ D( v& Z
     *(int * const)(0x67a9) = 0xaa55;% j8 R8 O3 m- [; o' g, x

2 _1 D. p. d; K; o# Y 即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。
7 e9 G1 k9 k0 n. E5 c2 u
% H7 U/ v& r& C" H/ ^1 P. J 中断(Interrupts)
( u# N( o( t+ m7 f# ^* N( V * q: K3 ]. B  N
11. 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。
6 R- v. @1 s* l3 G 1 W) N: T* Q' A. c: {
__interrupt double compute_area (double radius)
  q: f' }% K& ? {& A! B1 d1 L( N6 D
     double area = PI * radius * radius;
% x/ Q5 N+ E4 c     printf("\nArea = %f", area);( q/ A4 L* K# u6 o6 ]
     return area;" p! N( R& q/ `8 o1 a$ t. x$ I
}: J6 `# p/ z$ V. R/ E( y

: [3 o- o3 q% L( { 这个函数有太多的错误了,以至让人不知从何说起了:  f* m$ a+ s! o7 P4 [
1)ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。5 E) k# |% B+ U" \7 h0 b
2) ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。
+ q; u9 H9 K* w$ [' f 3) 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
( F. \6 s+ ]2 D 4) 与第三点一脉相承,printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。
* g' [) M. I; i3 G6 a" i+ n) C   ?' [! Z. D$ c0 x

; I! G6 B* M7 k* m' Q5 x. x 代码例子(Code examples)
% k- A: ^) H& Y; S# a; R, K
. \+ q5 L& c  C" Y& L 12 . 下面的代码输出是什么,为什么?
: v5 M4 d1 U8 M! P& s: Q
/ b2 {; I+ F1 i7 o* n  A void foo(void)
0 m! @+ X) y0 F7 G: y8 N5 Q% N8 X {7 K/ H, ]+ m7 C" A
     unsigned int a = 6;
- z* U" ?6 w- Z/ \     int b = -20;
6 v" \/ Z3 m9 f9 G% K% {6 P9 d     (a+b > 6) ? puts("> 6") : puts("<= 6");
' E' }, P& a, }! w  i2 s: f1 C }
0 T3 n$ }$ j" `& Z1 f 这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是 ">6"。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。
3 U, ?# Y: V! e% B' ^ ; y/ H2 i0 z0 s8 ^7 z
13. 评价下面的代码片断:
9 b, I: k5 b2 R8 B3 r5 ?  m# s9 H , }& d+ t# q3 ]. ?1 Y* j! F
unsigned int zero = 0;
. Z- q5 j2 A: }; F3 x, y% J) G; `6 k+ o unsigned int compzero = 0xFFFF;
6 x  {6 b5 N! E9 E8 k4 b  e /*1's complement of zero */7 o7 _0 V  t  F3 ^. z
5 A4 z; U6 k6 d, n& W: l' A# I
对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下:& |5 P: S/ f& _8 w. v
1 X7 c8 F( I  H9 C  C* p
unsigned int compzero = ~0;) T% _  m" |  x2 ?5 _9 D. F: u, B3 X

, u( F$ u2 o* g' ?" U7 m 这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里,好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼。; \. G' E; y7 a3 S( V# ?( [
到了这个阶段,应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好,那么这个测试就在这里结束了。但如果显然应试者做得不错,那么我就扔出下面的追加问题,这些问题是比较难的,我想仅仅非常优秀的应试者能做得不错。提出这些问题,我希望更多看到应试者应付问题的方法,而不是答案。不管如何,你就当是这个娱乐吧...( R. U0 x) H- ?/ K- H; N( {
: a1 i) N0 _8 @' l) u" e

$ m" d' z$ o! G& w3 A. x- D& r 动态内存分配(Dynamic memory allocation) $ N3 r( C5 m! R# D) J+ N1 J" U
) U1 c$ W6 }; W$ ]
14. 尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么?1 S% u) _9 L4 l( h4 v4 m
这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了(主要是 P.J. Plauger, 他的解释远远超过我这里能提到的任何解释),所有回过头看一下这些杂志吧!让应试者进入一种虚假的安全感觉后,我拿出这么一个小节目:! P! f  l' ^4 k
下面的代码片段的输出是什么,为什么?$ O5 @) Z! q. y* M9 I
# T; e" {. T/ n* x
char *ptr;
' j* O% c4 z/ B+ T7 ]7 B if ((ptr = (char *)malloc(0)) == NULL) ( T3 T, h. c+ b# H
     puts("Got a null pointer");
# P' ?9 ^( e9 Y6 h$ i$ u else
5 R8 t- p! P) q2 Y  m" w     puts("Got a valid pointer");
+ l0 t" F: s1 O 6 B9 G! o& g% q, u0 z2 b1 Z
这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的指针之后,我才想到这个问题。这就是上面的代码,该代码的输出是"Got a valid pointer"。我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要,但解决问题的方法和你做决定的基本原理更重要些。: u0 l9 e5 B) B& o8 E

5 p7 s9 A% x$ ?( b8 J Typedef ; w3 `, I) i( A+ j
  
; `+ T) [) p; l* r" u, K! Z" S 15 Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子:
) p8 ^5 ?' e* N8 @6 W! H" s
2 l5 q+ p6 i4 k# N% m! N #define dPS struct s *% O: x9 \% d) U7 a1 T0 D/ X
typedef struct s * tPS;
8 j8 T* u" A6 _3 r # @+ A3 l1 M4 O' |( y9 r% ?  Z
以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?
" T4 ~* V3 z* A( k% c$ o 这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子:
0 k2 \  A+ e) @- z + n7 U: a9 ^- y
dPS p1,p2;3 B4 m$ F- M' d+ w7 [. }
tPS p3,p4;
! G) {- h" M- B5 O* Q. ?; U
8 G% d$ A! d. {+ l+ l 第一个扩展为" o) W7 P) O! d8 u( x4 p
5 ?. S" X+ D$ v$ J
struct s * p1, p2;5 ?" z, y5 h: s7 ]! \# y
.
0 H% T$ m% J( q  {& g( x 上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。
0 |' J8 @' f) ]# X* g$ w" ?
2 A- J" q% w! g, f0 I9 S . `! @7 r* z5 J8 X
' o( f$ E. s1 o2 r; z+ S
晦涩的语法
. m% @, }* z: _
0 c# d, d. B  ?3 S( T6 B 16 . C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么?
5 ~& T6 |, H( e* j
+ \" x: g  x8 L! _& s& B int a = 5, b = 7, c;+ \8 ]9 e- p, J& n, L; b
c = a+++b;/ d6 q7 `' J4 j2 s! o7 |

: b+ \" U* Z+ h5 A2 i+ a 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成:, |8 _0 C; \* m( o1 Y4 e" I
- l: I# P, O/ e3 M+ h0 `- v
c = a++ + b;7 G8 \& W/ a& K6 s

4 f2 _$ N( Q/ H  x& i" N# `! D) g 因此, 这段代码持行后a = 6, b = 7, c = 12。
' w+ E* S; O3 q, `3 I' K. ]% @ 如果你知道答案,或猜出正确答案,做得好。如果你不知道答案,我也不把这个当作问题。我发现这个问题的最大好处是这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题。, M( X# L9 z# z3 x' R9 U

( f- ?! ?% ~) h: n& m3 t5 F
! k  z) e3 u- K) H0 h5 X- A8 s- _: M  n* w& W; f( e% @

! w! L  {. l: s5 I- q
/ s5 q& W- o6 Q1、将一个字符串逆序
3 L1 f" I  G; V8 D) o+ n2、将一个链表逆序 / k. J$ B! y% E! z9 U
3、计算一个字节里(byte)里面有多少bit被置1 ' o9 c' p+ O7 A" e! r  a9 t
4、搜索给定的字节(byte)
! {, j# F- E" {5、在一个字符串中找到可能的最长的子字符串
1 b2 R* `& {7 I6、字符串转换为整数 : a& k+ V2 F1 }7 t5 v* r
7、整数转换为字符串
posted @ 2009-09-14 12:50 life02 阅读(194) | 评论 (0)编辑 收藏

周立功单片机软件面试方面的部分题目和解答

1、        编写函数从一个包含由逗号分隔的100个16进制数的字符串中提取这100个16进制数,按从大到小的顺序输出其中的偶数。$ m; f1 y# }+ S9 M
解:此题按步骤解即可:先解析100个整数;再对其中的偶数排序;最后输出。
8 s7 O7 V8 v& E2 A( t
" g- Y! o, m' L#incluede<iostream>
1 X( s3 k2 q' n3 Q$ ~5 V: Rvoid coma(char *s,int b[],int bl)
9 k0 b4 j1 O( D2 C: Z0 P{8 j9 j  O. @/ o- Y2 e5 K  \' S% M
        int i,j=0,k;; i$ v  u0 G0 R6 i9 _( L/ w
   
/ Y' x$ l8 G1 l2 w4 I! G. o    //将字符串s按分隔符’,’解析成100个整数,存放在数组b中
$ [" ], q4 |9 e' V        for(i=0;i<bl;i++)
' u/ j1 o& y$ V) A" u# t1 f        {
8 r# ?; ?6 v9 Z2 g0 A* d            while(s[j]!=','&&j<strlen(s))
+ c* J: t, l2 l2 [4 D                {
/ Q; T6 Q( L% o4 Y5 h1 J" r                        if(s[j]>='0'&&s[j]<='9')# a8 d) o! I" M* }
                                k=s[j]-'0';5 |5 Z& \+ q4 P: G4 c
                        else if(s[j]>='a'&&s[j]<='f')
0 q( p9 D6 K) i                                k=s[j]-'a'+10;# S0 ~7 |* Q$ Q/ C" s
            b=b*16+k;
7 T7 V  P9 ]0 \+ v                        j++;* v; o" w) S  W) B- w4 X4 d
                }3 S/ V7 v" t; D6 D
                j++;
0 h1 s* c# B3 `0 V        }, @% |: T1 F* R" B  @" K
& a+ k+ U' M0 y% T
        int max;
% F* |; X' H3 D% \" f' ]5 w        int blen=bl;
1 w5 o  D4 N, X; W; q. k; \        int cur,t,even=0;. u% l7 z# e! h2 a/ M5 c& k1 ^
, p: e2 Y+ l/ E* X( T/ p
    //对b数组的偶数按从大到小排列,交换到数组的前端。
; m5 E1 p3 L: O3 p; ^7 `+ A9 D2 w        for(i=0;i<blen;i++): u" l/ v; a+ s/ L, l$ u3 R- b" v
        {
2 Y+ d# [  M- ?$ d, b                max=0;% A, ~3 B! I0 ^
                cur=-1;2 Q! H& O7 R; Z. h: F+ q
        //j从i开始,因为i以前已是有序偶数,且已从大到小排列
4 ~( I' I& G& z0 A( T            for(j=i;j<blen;j++)
! C9 |) V. R; [2 Q4 G9 y1 W( k                {
. x; \2 N9 u; {* X8 v+ \; Z                    if(b[j]>max&&b[j]%2==0)% I  M% S2 ]: k/ Y
                        {
# T1 n$ K" t9 K% k9 A                           max=b[j];1 [( `' G- I3 E8 r9 I
                           cur=j;2 k& P1 ?& A9 z$ J6 K) K
                        }- P( T" n% w4 \9 \0 F3 f. r
                }
5 g$ ^+ K0 r! `0 e3 r; O+ u6 ?5 H: d0 G' o' q
        //找到剩余数组中的最大值,交换到数组前端7 j+ ]+ T, |' ?  j. u7 Z
        if(cur!=-1)& Q( Q( w( Y3 j) }$ X
                {, X3 N& e8 S' W# k2 W# f
                    t=b[cur];
( T. y. d, Z1 A. G0 ~, I$ v                        b[cur]=b;
4 j' `) R( F/ A) I# f1 z+ B                        b=t;' d4 j# m& q" I1 Z
                        even++;$ w/ r6 o; _, j
                }
! g7 D! Z* x+ C0 E6 N0 J" T+ ?6 T        //剩余数组找不到偶数时,跳出循环' _7 \$ _2 n6 v
                else
: V+ Y# }' C6 E- L$ g* }8 x( d3 w8 f9 w                        break;, h8 g" Y+ R5 O$ h
        }
5 k3 G; o' c$ B6 a5 M7 |* F! V+ N( Y) u
    //输出前even个排序好的偶数3 q' F2 [3 g% u; Y5 f# [; s1 [
        for(i=0;i<even;i++). P1 H7 \3 K+ r9 K7 d8 H# K4 R
        //十六进制格式输出
& r5 Z; t7 L7 M9 j' A                cout<<hex<<b<<"  ";
" n' a7 `* G3 Y: Z  c+ s  l. A                //printf("%x  ",b);  n  o$ [, X( A# L# {" e
6 w6 \& k2 G( {/ W7 p5 n
    cout<<endl;& o6 A8 u& {3 k3 W" |0 T# b
    return;
  [1 D- i7 _  ~" S1 g/ @}
# V4 L3 T" m. ~- ^- ^* u2 y% Z! _" q1 _' h2 a& Z1 Y) X* @7 C
//测试: C9 N1 |; Y; J' s7 o( m+ g; l$ C
int main()' B3 R* k: ^, W; e
{! k9 [/ m  v: }. `/ f3 J2 A
char *s="1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f,60,61,62,63,64,65";: G/ h0 _' U1 Z6 R0 c
        int sb[100]={0};
% L* d0 c; W6 w/ b        coma(s,sb,100);
% q. ~) o. R, Y& v1 i& A6 Q3 Ereturn 0;
0 c; u! @+ K. s6 b4 J1 j: ^}6 K9 k/ ?* d- H5 u: P- T9 c
$ j* n6 Z0 r1 p! q- U) [
测试输出:+ P# b9 f9 Z' i' C; c! `2 e3 j  d! v
64 62 60 5e 5c 5a 58 56 54 52 50 4e 4c 4a 48 46 44 42 40 3e 3c 3a 38 36 34 32 30 2e 2c 2a 28 26 24 22 20 1e 1c 1a 18 16 14 12 10 e c a 8 6 4 2 0
. }. _! S) s' b8 x7 G4 E% \0 K5 r6 `' a  {0 Y
2、        编写函数数N个BYTE的数据中有多少位是1。4 K, o9 T9 Q) D, v
解:此题按步骤解:先定位到某一个BYTE数据;再计算其中有多少个1。叠加得解。
3 \7 y- ^& h: ^( v) E5 s
' I3 {$ {; h- z$ x0 ]: b#incluede<iostream>8 H7 T+ m2 @$ E& c
#define N 10
5 U) P% X9 M4 d' |! U- \//定义BYTE类型别名
: ^9 J; Y% X4 ^2 g#ifndef BYTE
# @4 K% X$ E: o5 y/ A9 {typedef unsigned char BYTE;
; V4 k3 Z8 t1 w$ [% F0 \#endif
2 {9 t8 ?( w6 E! H, l! d( V4 X) {( n: I# ?+ t2 |  s* r
int comb(BYTE b[],int n)' f9 r0 ?1 ?9 ~& M' ?: u
{
" C$ @% l/ U' S) ~% c) r" }  V- o& H    int count=0;' g( j& [7 ]7 P$ h6 [" J- p
        int bi,bj;  Q- I$ L" {) X, u5 l& {1 s* I
BYTE cc=1,tt;4 ~0 q4 G) q0 s* _  y* n

; S: }& K1 J8 M: @$ J  c//历遍到第bi个BYTE数据
5 R5 V% t" N, @  K        for(bi=0;bi<n;bi++)3 f3 z5 b7 U$ A2 n" {, y
        {
  c& x) _. X# A//计算该BYTE的8个bit中有多少个1  r5 [  ?! V; u0 ~) O7 y- f! b
                tt=b[bi];
) g6 R$ r: n- i: `0 p        for(bj=0;bj<8;bj++)
4 W8 O% k) r2 f& F, L                {
1 V. ]- b: N1 i! D0 |            //与1相与或模2结果是否是1?测试当前bit是否为1
% G' u5 ?* R7 C            //if(tt%2==1)& d! L  j3 _5 x% L
                    if((tt&cc)==1)
# Y3 w+ f' k2 T4 `% y3 _- v" f! J, K                        {
8 ^# D( P; {1 T- P* e                count++;
0 I7 [' h1 e3 C, [: I' U$ J            }
; Q9 R4 H4 k' f. q( e3 N. @            //右移一位或除以2,效果相同7 `" t! y, ]  e! l' I5 c2 @
                        //tt=tt>>1;
; l, _' ^$ S9 U* Q                        tt=tt/2;
; x) ^6 M# k% s/ @6 x$ l* M                }
' J& y% W$ u: l- Q5 s        }, E* V2 z& b, @# k4 }
        return count;
+ \& R7 C/ u2 K}
# g) i4 e- x0 D, d7 Y7 ?/ w( x( ^  l2 }8 Z% C9 A) t
//测试! ~' G" a# b0 |! v
int main()
& N+ T& m8 w: l/ P( y0 I: l{
9 d" E) d8 J" r2 j6 o/ b& QBYTE b[10]={3,3,3,11,1,1,1,1,1,1};
$ r. p, v+ r  ~3 n        cout<<comb(b,N)<<endl;
7 `  N( P- {5 X/ r    return 0;9 N7 M. _0 j8 y4 Y. I. V
}
+ u4 j  @* J0 O3 Z; X, F
6 R+ Z; H0 W" X测试输出:3 Q( s: a  Q3 O9 n7 R4 \# R  j! N
15
5 A' V0 n6 L6 j0 }6 z4 t
2 |  }7 |* ^+ s. A+ |$ [  _3、        编写函数比较两个字符串。
5 Q" g$ A( p# `8 c4 u. {解:此题简单,可能只要注意一下下标越界问题。
9 @1 `# h' ^( [0 k* u: }5 n+ S9 h; a. E# q
#incluede<iostream>0 a$ s2 p' Y% j3 ]7 g& [5 }* n
int mstrcmp(char *st1,char *st2)& \5 T) U% p7 q4 b
{  l6 l7 M# l! F8 s8 o4 X$ v$ j
    /*注意到当st1,st2任一为空时,*st1==*st2测试为假;当st1,st2同时为空时,*st1==*st2语句为假,故不会越界。*/
2 w& _9 f  u7 g, I) S  B) t        while(*st1==*st2)9 j* j* A5 ^2 @- i
        {( ~2 w! I7 X1 m8 V
                st1++;( i, ~# B* U6 }
                st2++;               
5 X4 _, O9 H. `7 I( K& o2 X        }
8 V# X1 c- v# r. N2 E# q        if(*st1>*st2), Y/ y2 R* ]4 _5 G- M# w
                return 1;
& S5 n% @% @7 k2 t9 w% a' \        else if(*st1<*st2)% q* p" ^" _3 l! K& R8 f
                return -1;& a, W# x" d' h
        else 9 W$ U) Q- I, f1 D' ^
                return 0;6 G& x' j  f8 S9 f: Y9 q1 V1 k
}
( J+ t0 L- j0 u7 B! ~, i$ K
1 W7 }  Q9 H3 d//测试; w! H  ~' u6 D% g, h
int main()
9 x- Z4 K+ i9 O  ?9 F/ W7 `{
- q, G3 e# s) [    char* x1="def2";: S# n$ t! j# A
        char* x2="def223";
" [$ ]/ C5 O' W: V1 V/ ]    //c标准库自带字符串比较函数
0 Z5 i$ r' y9 r' Y        cout<<strcmp(x1,x2)<<endl;2 j! U6 \( W' j5 ]2 B
    //自己写的' ?* X, ~! H9 @% G% g
    cout<<mstrcmp(x1,x2)<<endl;8 E$ s+ q# g5 x5 T( b
}
0 F$ m, R7 _& g% V; B  v1 i4 C) Y% Q2 r. h6 j
测试输出:$ b) F- i9 P& ]: o3 R
-1
% u9 C7 ?) D5 E-1
1 c: f: E) ]7 g8 R9 W3 D* D3 v% B# f- B
4、        计算一个结构占的字节数,及在紧凑模式下占的字节数。. r$ H0 G1 R  R& U4 J/ B" k8 x
解:char占1个字节;int占4个;short占2个;long占4个。考虑到位对齐:char 占1-4字节;int占4-8字节;short占8-12字节;long占12-16字节。紧凑下不知道如何编写代码,但应该不用位对齐,故估计输出应为:11,00000007。) ]  O2 a3 c* W; h( q+ ~
这里要提醒大家的是:位对齐与类型的排列顺序有关。若类型排列为:int char short long,则int 占1-4字节;char占4-6字节;short占6-8字节;long占8-12字节;此题输出应为:12,00000008。
, n, A4 V4 u1 f1 x
1 X1 c8 q$ k( k$ X  c8 _#incluede<iostream>
8 t/ @2 r  o8 x: ^0 R0 D: l" ktypedef struct _st4 Q8 M6 e/ j0 ~: p( a9 N8 Z
{
( y( y5 e4 j- y/ M8 _! B9 y) s    char a;
6 m1 o+ c* u+ q9 g( Y" K7 s0 G        int b;9 b% L& u2 {* u" `. R2 ~) ^
        short c;: f, x- h$ C/ }  n( P9 }/ B" L' b
        long d;6 l+ j" F: d" ~7 P" _
}0 u1 N/ N! A# [" O; k
st;
1 r/ b7 I8 o9 d9 j8 I; K" S9 v  b, r3 R$ d
//测试:
6 j$ l" o" a, z& Oint main()  A. D) ^* `) A- j" H7 R
{6 q; s3 Q9 ]2 m2 P) }3 K: o- P
    cout<<sizeof(st)<<endl;
0 R5 ?+ P9 I; N7 u2 y5 ?, I        cout<<&(((st*)0)->d)<<endl;* \4 _# K' j: W- e# h" _. y
    return 0;
9 J2 `; G/ {# Q}
# x, @- ]0 D* J6 R* O4 t) |
. E5 w3 x4 X' u1 s, {测试输出:4 l. D. u; S! h, @) z, N  \+ G
16
/ P7 I9 {; a$ f; p8 K0000000C# M( _0 r0 x: T5 t3 L
注:如何定义紧凑模式?求紧凑模式下的代码。7 s+ s! Q& S5 |) E) O$ a" ^) P

& o+ B! ]) `5 o, S) U5、        多继承。
' A% \2 }. k  P解:virtual继承是防止a-b,c-d型继承时维护超基类a的两个版本。此题中virtual继承不影响构造及析构函数的调用顺序。此题另一个需要注意的是:new开辟类空间时需要调用构造函数;只当该类空间被delete释放时,相应类实例才会被析构。) u; n% u3 l4 U; \( \

" h- e+ i+ {4 L  e, g#incluede<iostream>& M1 v1 I9 i& B) k
class a7 j; T. l- v3 |# `/ L3 h! [
{
# ?, {, A: @$ }2 Spublic: ; ~& |8 i* B# V: j) U) ~6 R
        a(){cout<<"a"<<endl;}- e" Y: K; a# x9 ]# L
        ~a(){cout<<"~a"<<endl;}
! q6 w' \3 C7 y};- C8 B" `9 a& N  q% d7 B* T

2 \# r$ F: _' \class b : virtual a
4 Z+ `! {$ K/ @% Z{
: R: C9 t" a( B1 I$ @public:
' m) W0 j. q* w( {$ |2 c        b(){cout<<"b"<<endl;}$ v' D8 Z( z3 ^1 g+ V7 v# H- F+ X7 \
    ~b(){cout<<"~b"<<endl;}
3 }) p( U+ T3 D! `};
4 o2 O) {& ^' K& T2 J" l5 P& [4 Q) ^/ z9 {" ?! q' Y3 k
class c 6 j4 p  x6 |0 T1 o! W3 e
{
6 v, t. D6 U& }9 z  kpublic:
4 L. F; i1 d( T4 S& B/ Q) ^# C        c(){cout<<"c"<<endl;}8 @6 w4 ~& Q! d  y0 Y) W. q1 i
        ~c(){cout<<"~c"<<endl;}* Z) T$ d, g2 U7 M$ l
};
4 F4 ~3 j3 ~1 _+ e* n# i( ?
& q: O+ s+ d2 N. @class d : public c  A1 n8 ]3 X. K& T4 T
{) r0 r; c  n1 \2 k2 c
public:
5 c/ I* [- ]- P        d(){cout<<"d"<<endl;}
  b( i+ {# k1 o, m        ~d(){cout<<"~d"<<endl;}
9 l& i8 W. P- Q: y# [" u6 B};' m7 U( D  ]8 A5 }$ ]

- p: O1 _  t/ x- p/ fclass e : public b, public d
6 O( o+ _6 W& m7 ?, [  r{
; s; \  y# }* z+ d3 R$ e1 p1 n( fpublic:
0 D( H* t  D" O$ _" V+ c, |        e(){cout<<"e"<<endl;}
/ k3 S4 x( R% R/ O        ~e(){cout<<"~e"<<endl;}
5 y; m# T8 N) e9 w};; \. C9 ^5 W( o, u1 r0 N

* C; A1 o# x* i( X" [0 p//测试
& F0 o8 o9 _* Q+ M4 x- cint main()
0 n: N, Y+ C6 M$ V0 k{* X/ a- T7 K9 j  ~" x7 J  a
e es;9 X1 W# u7 C% A/ J1 ?2 V  n) @  p! m
        e *ep=new e;0 R8 \) _2 N/ h* J$ w( t
        //delete ep;
/ q2 Z+ m( B. [1 \7 M5 z8 s    return 0;# v) x5 {, ?& s* i: T
}
, y; }+ J6 c6 U; \8 C4 _- ~8 ^$ B+ L: v& \+ d
//测试输出
6 X' u( B3 n) j6 c( e' Ca
9 A% p7 _: n1 J" `) G( M% {b6 V( u) Q7 z0 z9 ?# P6 `' s
c7 e5 l* r; T$ W
d
* r+ m+ a) z, i! Ie8 Y5 G6 T7 z( A& Q- b
a2 C. R) E/ A& @5 Q4 z! k
b4 i7 u! z9 L5 j. b  O
c
: }- c9 V% S2 ~9 zd5 p$ Y4 I" R% h+ |* G
e
, `' q9 l( A9 Y9 l$ N" m* _# S~e
5 x2 i% T6 R2 X% A" t5 W~d' L# S- N0 e0 |" E  q4 f: e2 J
~c+ g3 d  T5 R2 p8 T( M7 m4 m
~b+ }7 m5 F3 L& S- m- a
~a8 m0 y. U" z) x
4 p: L  }* Y8 N
6、        编写String类,实现加法和赋值运算符重载。
2 D& L; F5 h5 g解:此题名不见经传,实现中需要注意:必须实现拷贝构造函数,在加法重载中返回一个类实例才能成功。' T3 L& B0 X5 U% @& r, M/ N+ F

. Q/ J* L, L- R% G#incluede<iostream>1 Q- `; |2 G4 E4 O7 R% ^+ b  c$ ]
class String+ c2 s3 Q9 c- o( L8 b/ o+ D- V, {
{
* g* O' S. m1 s" @5 Xpublic:$ F( H" }$ f/ u' P
    //构造函数5 G- M; @  s- b& ~( Z; t2 d5 M: e" a
    String(char *s=0,int len=0):len(len)
3 n  n) n; n) q8 ?, a; z, _" h        {, \: \1 u1 ^' c& G1 g) d7 J
                this->s=new char[len];
3 w- t+ I3 I9 x  n. l1 n            int i;
2 L# o( Q# Q; e+ N                for(i=0;i<len;i++)
" r" _) g4 C# Z3 p" A( b4 s                        this->s=s;
3 W+ a% L) c5 ~3 z        }+ E; a/ x! D9 s! `9 I
        //析构函数
! j2 }, Q6 |* g4 k        ~String(){delete []s;len=0;}) ]) I) u' v3 w3 K2 y2 t$ P
    void prints();7 d  ?- I) {9 ?" ]6 }- N' C
        String(const String &str);
; G& i/ v- v) q; j9 U2 Z$ E7 a: r        String& operator=(const String &str);
& \" Y. D. d" S  F: R, S- U' S9 N5 ^        String operator+(const String &str);
! G8 V* V( [: l7 [protected:% d; M5 j* j2 Z2 c
        char *s;/ z8 q: Z( z8 j7 C
        int len;6 y7 l1 H8 }% ^. z! n5 T
};# O4 f0 J5 h% K( E+ H. ]
6 T* i2 Z* }  j" [* R$ r/ p
//打印函数
. t% I2 S0 r( B; P5 U* y+ e* zvoid String::prints(), z* O; {& Y$ y7 k+ G9 Y
{9 T( R8 q9 b6 W7 l9 T* Y9 i: o% `
        int i;6 L% F- p1 w1 e: n0 a
    for(i=0;i<len;i++)
! X, g0 t! P' G5 |/ e9 w7 _4 ^                cout<<s;
2 q- X4 L# ]# C9 G* b9 G        cout<<endl;
6 i1 K2 B" w. z) N}
- k) k5 k# V4 h: K/ U( f8 {: \3 J' H' ~% p+ Z8 V/ ^! _7 \+ d
//赋值运算符重载$ X: @' r* [7 {  ?/ g/ B: u9 @
String& String::operator=(const String &str)
$ I* R% V7 A2 H0 {{" n; z. P! a) N6 R
    delete []s;7 j* ]& ^# k! T$ U% W* q
        len=str.len;) G* I- X7 V5 ^4 p3 }" l& N
        s=new char[len];
8 m6 `- u& H% \        int i;/ ?! K8 G( m+ `. _
        for(i=0;i<len;i++)
- g* N, U" B" t- L                s=str.s;
2 h. k8 _' n# T1 f: [/ D. y4 y        return *this;
7 p; n9 C( S+ @4 v4 C* J! _}, b, c) v* U9 R$ u( T" U" y7 C

' v) D3 M9 f9 \8 i//加法运算符重载3 b4 u0 I/ L  z- `/ e2 @
inline String String::operator+(const String &str)
- C7 X) C" O, A: ?9 u{
" H! X( d1 _" y! t3 I    String st(s,len+str.len);
( ]! M+ v& m! ~0 g1 q8 y9 p        int i;, N. `1 Q4 }% {
        for(i=len;i<st.len;i++)
; ^4 a4 v& g% u( ?( E3 P                st.s=str.s[i-len];
$ W8 j( }9 q  s# y3 a' o1 Z0 {3 s/ H        return st;
- x8 R/ d. E, V: O8 P}
- S7 @; l5 b/ B# B( ^; c) i: f
+ B5 m& [4 M( d* F! E//拷贝构造函数* T% g9 K# f; G) P& p6 I
String::String(const String &str), d$ m: o1 @$ d" t8 g; |
{
, H5 X2 m4 J# h- H: R# X        len=str.len;( q" x/ M. k* y' O' ]6 I( z
        s=new char[len];
0 E8 Z  ?0 P: c( F% @; S        int i;
2 j4 W9 C3 N- G$ r% A  j/ @" R        for(i=0;i<len;i++)
& a. Z: V/ E' o. C                s=str.s;
' A* f# q8 i  I& I, y( p# O9 {; Z}
2 H% s0 w; i  c& V
% W( c4 \/ z* Y7 o7 Z9 @//测试+ b7 C) X& x* k0 `0 A
int main()5 z5 B+ C0 w: F2 L6 H6 @: N' }
{2 }, k1 h: l! r; l8 b. w& Q2 ?
        char *s1="123";
/ U; h: B& |& Z        char *s2="4567";
7 U4 X6 {. ?5 q: i1 z
% H& n' B# r6 @    //第一个字符串
9 {5 b$ z# f! e- @- m    String str(s1,3);% u- n" V1 x3 Q0 O* f0 g
        str.prints();1 ^2 a( v0 a, q+ V- M7 K$ L

3 A& O5 \2 Q( ?  |: i) J8 w    //第二个字符串
/ r& ]: ]  ~  a/ c) |/ \. w* X        String str2(s2,4);& J* P9 ?- f. p- a! I2 I& K  Q4 Q
        str2.prints();
' r$ j) j) }+ G4 \' _: g! ]7 K5 ^
: @* Z: n1 R; k' h  {- l    //赋值运算符重载测试+ P6 q% r4 }( c/ i; @
        String st;
  a8 }9 e: a  _% ^% I8 y( T        st=str;
3 e- {! O/ \. N, \0 r6 i        st.prints();
- w' {; c/ q- v* M; j, q2 e; g2 Q5 {" w3 r2 s
    //加法运算符重载测试
& H7 N% w5 {* j% h& r6 Q4 A( {. b        String string;
. p  J' O/ P6 j. H, c' K' _* ~        string=str+str2;9 a% R  A/ T& j& S( Z3 d) X
        string.prints();0 L: ^" y! {0 l! |0 c3 m

! n- B2 z7 }0 l* Rreturn 0;" _' Q) Q! \. M! c; Q- [" Y# L
}. c8 i' _$ z) H3 B7 A

( @% ]# j& H+ m  \( r  {6 K' {. z% n测试输出:
* m0 ?% `! z1 \+ k: Q, L123
5 B+ L4 N! h. I7 y$ c( s. t4567+ C& i; H' C0 P. i
123
! V/ g, i  s5 c6 K; m6 x
posted @ 2009-09-14 12:48 life02 阅读(1166) | 评论 (0)编辑 收藏

String 类的原型如下

class String
{
   public:
          String(const char *str=NULL); //
构造函数
          String(const String &other); //
拷贝构造函数
          ~String(void); //
析构函数
          String& operator=(const String &other); //
等号操作符重载

          ShowString();


   private:
          char *m_data; //
指针
};


String::~String()
{
    delete [] m_data; //
析构函数,释放地址空间
}
String::String(const char *str)
{
    if (str==NULL)//
当初始化串不存在的时候,为m_data申请一个空间存放'\0'
     {
        m_data=new char[1];
        *m_data='\0';
     }
    else//
当初始化串存在的时候,为m_data申请同样大小的空间存放该串;
     {
        int length=strlen(str);
        m_data=new char[length+1];
        strcpy(m_data,str);
     }
}


String::String(const String &other)//
拷贝构造函数,功能与构造函数类似。
{
    int length=strlen(other.m_data);
    m_data=new [length+1];
    strcpy(m_data,other.m_data);
}
String& String::operator =(const String &other)
{
    if (this==&other)//
当地址相同时,直接返回;
        return *this; 
 
    delete [] m_data;//
当地址不相同时,删除原来申请的空间,重新开始构造;

    int length=sizeof(other.m_data);
    m_data=new [length+1];
    strcpy(m_data,other.m_data);

    return *this; 
}

 

String::ShowString()//由于m_data是私有成员,对象只能通过public成员函数来访问;

{

      cout<<this->m_data<<endl;

}

 

 

 

main()
{
String AD;
char * p="ABCDE";
String B(p);
AD.ShowString();
AD=B;
AD.ShowString();


}

posted @ 2009-09-14 09:35 life02 阅读(312) | 评论 (0)编辑 收藏

仅列出标题
共20页: First 12 13 14 15 16 17 18 19 20