版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、想成为嵌入式程序员应知道的0 x10个基本问题 HYPERLINK xx3722x/ C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为面试者和被面试者提供许多有用信息,此外,撇开面试的压力不谈,这种测试也是相当有趣的。 从被面试者的角度来讲,你能了解许多关于出题者或监考者的情况。这个测试只是出题者为显示其对ANSI标准细节的知识而不是技术技巧而设计吗?这是个愚蠢的问题吗?如要你答出某个字符的ASCII值。这些问题着重考察你的系统调用和内存分配策略方面的能力吗?这标志着出题者也许花时间在微机上而不是在嵌入式系统上。如果
2、上述任何问题的答案是是的话,那么我知道我得认真考虑我是否应该去做这份工作。 从面试者的的角度来来讲,一一个测试试也许能能从多方方面揭示示应试者者的素质质:最基基本的,你你能了解解应试者者C语言言的水平平。不管管怎么样样,看一一下这人人如何回回答他不不会的问问题也是是满有趣趣。应试试者是以以好的直直觉做出出明智的的选择,还还是只是是瞎蒙呢呢?当应应试者在在某个问问题上卡卡住时是是找借口口呢,还还是表现现出对问问题的真真正的好好奇心,把把这看成成学习的的机会呢呢?我发发现这些些信息与与他们的的测试成成绩一样样有用。 有了这些想想法,我我决定出出一些真真正针对对嵌入式式系统的的考题,希希望这些些令人
3、头头痛的考考题能给给正在找找工作的的人一点点帮助。这这些问题题都是我我这些年年实际碰碰到的。其其中有些些题很难难,但它它们应该该都能给给你一点点启迪。 这个测试适适于不同同水平的的应试者者,大多多数初级级水平的的应试者者的成绩绩会很差差,经验验丰富的的程序员员应该有有很好的的成绩。为为了让你你能自己己决定某某些问题题的偏好好,每个个问题没没有分配配分数,如如果选择择这些考考题为你你所用,请请自行按按你的意意思分配配分数。 预处理器(PPrepproccesssor) 1 . 用用预处理理指令#deffinee 声明明一个常常数,用用以表明明1年中中有多少少秒(忽忽略闰年年问题) #defiin
4、e SECCONDDS_PPER_YEAAR (60 * 660 * 244 * 3655)ULL 我在这想看看到几件件事情: 1) #ddefiine 语法的的基本知知识(例例如:不不能以分分号结束束,括号号的使用用,等等等) 2)懂得预预处理器器将为你你计算常常数表达达式的值值,因此此,直接接写出你你是如何何计算一一年中有有多少秒秒而不是是计算出出实际的的值,是是更清晰晰而没有有代价的的。 3) 意识识到这个个表达式式将使一一个166位机的的整型数数溢出-因此要要用到长长整型符符号L,告诉编编译器这这个常数数是的长长整型数数。 4) 如果果你在你你的表达达式中用用到ULL(表示示无符号号长
5、整型型),那那么你有有了一个个好的起起点。记记住,第第一印象象很重要要。 2 . 写写一个标准宏MIIN ,这这个宏输输入两个个参数并并返回较较小的一一个。 #defiine MINN(A,B) (AA) = (B) ? (A) : (B) 这个测试是是为下面面的目的的而设的的: 1) 标识识#deefinne在宏宏中应用用的基本本知识。这这是很重重要的。因因为在 嵌入(inllinee)操作作符 变变为标准准C的一一部分之之前,宏宏是方便便产生嵌嵌入代码码的唯一一方法,对对于嵌入入式系统统来说,为为了能达达到要求求的性能能,嵌入入代码经经常是必必须的方方法。 2)三重条条件操作作符的知知识。
6、这这个操作作符存在在C语言言中的原原因是它它使得编编译器能能产生比比if-theen-eelsee更优化化的代码码,了解解这个用用法是很很重要的的。 3) 懂得得在宏中中小心地地把参数数用括号号括起来来 4) 我也也用这个个问题开开始讨论论宏的副副作用,例例如:当当你写下下面的代代码时会会发生什什么事? leastt = MINN(*pp+, b); 3. 预处处理器标标识#eerroor的目目的是什什么? 如果你不知知道答案案,请看看参考文文献1。这这问题对对区分一一个正常常的伙计计和一个个书呆子子是很有有用的。只只有书呆呆子才会会读C语语言课本本的附录录去找出出象这种种问题的的答案。当当然
7、如果果你不是是在找一一个书呆呆子,那那么应试试者最好好希望自自己不要要知道答答案。 死循环(IInfiinitte lloopps) 4. 嵌入入式系统统中经常常要用到到无限循循环,你你怎么样样用C编编写死循循环呢? 这个问题用用几个解解决方案案。我首首选的方方案是: whilee(1) 一些程序员员更喜欢欢如下方方案: for(;) 这个实现方方式让我我为难,因因为这个个语法没没有确切切表达到到底怎么么回事。如如果一个个应试者者给出这这个作为为方案,我我将用这这个作为为一个机机会去探探究他们们这样做做的基本本原理。如如果他们们的基本本答案是是:我我被教着着这样做做,但从从没有想想到过为为什么
8、。这会给给我留下下一个坏坏印象。 第三个方案案是用 gotto Loop: . goto Looop; 应试者如给给出上面面的方案案,这说说明或者者他是一一个汇编编语言程程序员(这这也许是是好事)或或者他是是一个想想进入新新领域的的BASSIC/FORRTRAAN程序序员。 数据声明(DDataa deeclaarattionns) 5. 用变变量a给给出下面面的定义义 a) 一个个整型数数(Ann inntegger) b)一个指指向整型型数的指指针( A ppoinnterr too ann inntegger) c)一个指指向指针针的的指指针,它它指向的的指针是是指向一一个整型型数( A
9、 ppoinnterr too a poiinteer tto aan iinteege)rr d)一个有有10个个整型数数的数组组( AAn aarraay oof 110 iinteegerrs) e) 一个个有100个指针针的数组组,该指指针是指指向一个个整型数数的。(AAn aarraay oof 110 ppoinnterrs tto iinteegerrs) f) 一个个指向有有10个个整型数数数组的的指针( A ppoinnterr too ann arrrayy off 100 innteggerss) g) 一个个指向函函数的指指针,该该函数有有一个整整型参数数并返回回一个整
10、整型数(AA poointter to a ffuncctioon tthatt taakess ann inntegger as an arggumeent andd reeturrns an inttegeer) h) 一个个有100个指针针的数组组,该指指针指向向一个函函数,该该函数有有一个整整型参数数并返回回一个整整型数( An arrray of tenn poointterss too fuuncttionns tthatt taake an inttegeer aarguumennt aand retturnn ann inntegger ) 答案是: a) innt aa; /
11、 AAn iinteegerr b) innt *a; / A ppoinnterr too ann inntegger c) innt *a; / A poiinteer tto aa poointter to an inttegeer d) innt aa100; / An arrray of 10 inttegeers e) innt *a110; / Ann arrrayy off 100 poointterss too innteggerss f) innt (*a)100; / A ppoinnterr too ann arrrayy off 100 innteggerss g)
12、innt (*a)(innt); / A poiinteer tto aa fuuncttionn a thaat ttakees aan iinteegerr arrgummentt annd rretuurnss ann inntegger h) innt (*a10)(iint); / AAn aarraay oof 110 ppoinnterrs tto ffuncctioons thaat ttakee ann inntegger arggumeent andd reeturrn aan iinteegerr 人们经常声声称这里里有几个个问题是是那种要要翻一下下书才能能回答的的问题,
13、我我同意这这种说法法。当我我写这篇篇文章时时,为了了确定语语法的正正确性,我我的确查查了一下下书。但但是当我我被面试试的时候候,我期期望被问问到这个个问题(或或者相近近的问题题)。因因为在被被面试的的这段时时间里,我我确定我我知道这这个问题题的答案案。应试试者如果果不知道道所有的的答案(或或至少大大部分答答案),那那么也就就没有为为这次面面试做准准备,如如果该面面试者没没有为这这次面试试做准备备,那么么他又能能为什么么出准备备呢? Statiic 6. 关键键字sttatiic的作作用是什什么? 这个简单的的问题很很少有人人能回答答完全。在在C语言言中,关关键字sstattic有有三个明明显的
14、作作用: 1)在函数数体,一一个被声声明为静静态的变变量在这这一函数数被调用用过程中中维持其其值不变变。 2) 在模模块内(但但在函数数体外),一一个被声声明为静静态的变变量可以以被模块块内所用用函数访访问,但但不能被被模块外外其它函函数访问问。它是是一个本本地的全全局变量量。 3) 在模模块内,一一个被声声明为静静态的函函数只可可被这一一模块内内的其它它函数调调用。那那就是,这这个函数数被限制制在声明明它的模模块的本本地范围围内使用用。 大多数应试试者能正正确回答答第一部部分,一一部分能能正确回回答第二二部分,同同是很少少的人能能懂得第第三部分分。这是是一个应应试者的的严重的的缺点,因因为他
15、显显然不懂懂得本地地化数据据和代码码范围的的好处和和重要性性。 Constt 7关键字字connst有有什么含含意? 我只要一听听到被面面试者说说:cconsst意味味着常数数,我我就知道道我正在在和一个个业余者者打交道道。去年年Dann Saaks已已经在他他的文章章里完全全概括了了connst的的所有用用法,因因此ESSP(译译者:EEmbeeddeed SSysttemss Prrogrrammmingg)的每每一位读读者应该该非常熟熟悉coonstt能做什什么和不不能做什什么.如如果你从从没有读读到那篇篇文章,只只要能说说出coonstt意味着着只读读就可可以了。尽尽管这个个答案不不是
16、完全全的答案案,但我我接受它它作为一一个正确确的答案案。(如如果你想想知道更更详细的的答案,仔仔细读一一下Saaks的的文章吧吧。) 如果应试者者能正确确回答这这个问题题,我将将问他一一个附加加的问题题: 下面的声明明都是什什么意思思? constt innt aa; int cconsst aa; constt innt *a; int * coonstt a; int cconsst * a connst; /*/ 前两个的作作用是一一样,aa是一个个常整型型数。第第三个意意味着aa是一个个指向常常整型数数的指针针(也就就是,整整型数是是不可修修改的,但但指针可可以)。第第四个意意思a是是
17、一个指指向整型型数的常常指针(也也就是说说,指针针指向的的整型数数是可以以修改的的,但指指针是不不可修改改的)。最最后一个个意味着着a是一一个指向向常整型型数的常常指针(也也就是说说,指针针指向的的整型数数是不可可修改的的,同时时指针也也是不可可修改的的)。如如果应试试者能正正确回答答这些问问题,那那么他就就给我留留下了一一个好印印象。顺顺带提一一句,也也许你可可能会问问,即使使不用关关键字 connst,也也还是能能很容易易写出功功能正确确的程序序,那么么我为什什么还要要如此看看重关键键字coonstt呢?我我也如下下的几下下理由: 1) 关键键字coonstt的作用用是为给给读你代代码的人
18、人传达非非常有用用的信息息,实际际上,声声明一个个参数为为常量是是为了告告诉了用用户这个个参数的的应用目目的。如如果你曾曾花很多多时间清清理其它它人留下下的垃圾圾,你就就会很快快学会感感谢这点点多余的的信息。(当当然,懂懂得用cconsst的程程序员很很少会留留下的垃垃圾让别别人来清清理的。) 2) 通过过给优化化器一些些附加的的信息,使使用关键键字coonstt也许能能产生更更紧凑的的代码。 3) 合理理地使用用关键字字connst可可以使编编译器很很自然地地保护那那些不希希望被改改变的参参数,防防止其被被无意的的代码修修改。简简而言之之,这样样可以减减少buug的出出现。 Volattil
19、ee 8. 关键键字voolattilee有什么么含意?并给出出三个不不同的例例子。 一个定义为为vollatiile的的变量是是说这变变量可能能会被意意想不到到地改变变,这样样,编译译器就不不会去假假设这个个变量的的值了。精精确地说说就是,优优化器在在用到这这个变量量时必须须每次都都小心地地重新读读取这个个变量的的值,而而不是使使用保存存在寄存存器里的的备份。下下面是vvolaatille变量量的几个个例子: 1) 并行行设备的的硬件寄寄存器(如如:状态态寄存器器) 2) 一个个中断服服务子程程序中会会访问到到的非自自动变量量(Noon-aautoomattic varriabbless)
20、3) 多线线程应用用中被几几个任务务共享的的变量 回答不出这这个问题题的人是是不会被被雇佣的的。我认认为这是是区分CC程序员员和嵌入入式系统统程序员员的最基基本的问问题。搞搞嵌入式式的家伙伙们经常常同硬件件、中断断、RTTOS等等等打交交道,所所有这些些都要求求用到vvolaatille变量量。不懂懂得voolattilee的内容容将会带带来灾难难。 假设被面试试者正确确地回答答了这是是问题(嗯嗯,怀疑疑是否会会是这样样),我我将稍微微深究一一下,看看一下这这家伙是是不是直直正懂得得vollatiile完完全的重重要性。 1)一个参参数既可可以是cconsst还可可以是vvolaatille吗
21、?解释为为什么。 2); 一一个指针针可以是是vollatiile 吗?解解释为什什么。 3); 下下面的函函数有什什么错误误: int ssquaare(vollatiile intt *pptr) returrn *ptrr * *pttr; 下面是答案案: 1)是的。一一个例子子是只读读的状态态寄存器器。它是是vollatiile因因为它可可能被意意想不到到地改变变。它是是connst因因为程序序不应该该试图去去修改它它。 2); 是是的。尽尽管这并并不很常常见。一一个例子子是当一一个中服服务子程程序修该该一个指指向一个个buffferr的指针针时。 3) 这段段代码有有点变态态。这段段
22、代码的的目的是是用来返返指针*ptrr指向值值的平方方,但是是,由于于*pttr指向向一个vvolaatille型参参数,编编译器将将产生类类似下面面的代码码: int ssquaare(vollatiile intt *pptr) int aa,b; a = *ptrr; b = *ptrr; returrn aa * b; 由于*pttr的值值可能被被意想不不到地该该变,因因此a和和b可能能是不同同的。结结果,这这段代码码可能返返不是你你所期望望的平方方值!正正确的代代码如下下: long squuaree(voolattilee innt *ptrr) int aa; a = *ptrr
23、; returrn aa * a; 位操作(BBit mannipuulattionn) 9. 嵌入入式系统统总是要要用户对对变量或或寄存器器进行位位操作。给给定一个个整型变变量a,写写两段代代码,第第一个设设置a的的bitt 3,第第二个清清除a 的biit 33。在以以上两个个操作中中,要保保持其它它位不变变。 对这个问题题有三种种基本的的反应 1)不知道道如何下下手。该该被面者者从没做做过任何何嵌入式式系统的的工作。 2) 用bbit fieeldss。Biit ffiellds是是被扔到到C语言言死角的的东西,它它保证你你的代码码在不同同编译器器之间是是不可移移植的,同同时也保保证了的
24、的你的代代码是不不可重用用的。我我最近不不幸看到到 Innfinneonn为其较较复杂的的通信芯芯片写的的驱动程程序,它它用到了了bitt fiieldds因此此完全对对我无用用,因为为我的编编译器用用其它的的方式来来实现bbit fieeldss的。从从道德讲讲:永远远不要让让一个非非嵌入式式的家伙伙粘实际际硬件的的边。 3) 用 #deefinnes 和 bbit massks 操作。这这是一个个有极高高可移植植性的方方法,是是应该被被用到的的方法。最最佳的解解决方案案如下: #defiine BITT3 (0 x11 66) ? puuts( 6) : putts(66。原原因是当当表达
25、式式中存在在有符号号类型和和无符号号类型时时所有的的操作数数都自动动转换为为无符号号类型。因因此-220变成成了一个个非常大大的正整整数,所所以该表表达式计计算出的的结果大大于6。这这一点对对于应当当频繁用用到无符符号数据据类型的的嵌入式式系统来来说是丰丰常重要要的。如如果你答答错了这这个问题题,你也也就到了了得不到到这份工工作的边边缘。 一三. 评评价下面面的代码码片断: unsiggnedd innt zzeroo = 0; unsiggnedd innt ccomppzerro = 0 xxFFFFF; /*1ss coompllemeent of zerro */ 对于一个iint型型
26、不是116位的的处理器器为说,上上面的代代码是不不正确的的。应编编写如下下: unsiggnedd innt ccomppzerro = 00; 这一问题真真正能揭揭露出应应试者是是否懂得得处理器器字长的的重要性性。在我我的经验验里,好好的嵌入入式程序序员非常常准确地地明白硬硬件的细细节和它它的局限限,然而而PC机机程序往往往把硬硬件作为为一个无无法避免免的烦恼恼。 到了这个阶阶段,应应试者或或者完全全垂头丧丧气了或或者信心心满满志志在必得得。如果果显然应应试者不不是很好好,那么么这个测测试就在在这里结结束了。但但如果显显然应试试者做得得不错,那那么我就就扔出下下面的追追加问题题,这些些问题是
27、是比较难难的,我我想仅仅仅非常优优秀的应应试者能能做得不不错。提提出这些些问题,我我希望更更多看到到应试者者应付问问题的方方法,而而不是答答案。不不管如何何,你就就当是这这个娱乐乐吧. 动态内存分分配(DDynaamicc meemorry aalloocattionn) 14. 尽尽管不像像非嵌入入式计算算机那么么常见,嵌嵌入式系系统还是是有从堆堆(heeap)中中动态分分配内存存的过程程的。那那么嵌入入式系统统中,动动态分配配内存可可能发生生的问题题是什么么? 这里,我期期望应试试者能提提到内存存碎片,碎碎片收集集的问题题,变量量的持行行时间等等等。这这个主题题已经在在ESPP杂志中中被广
28、泛泛地讨论论过了(主主要是 P.JJ. PPlauugerr, 他他的解释释远远超超过我这这里能提提到的任任何解释释),所所有回过过头看一一下这些些杂志吧吧!让应应试者进进入一种种虚假的的安全感感觉后,我我拿出这这么一个个小节目目: 下面的代码码片段的的输出是是什么,为为什么? char *pttr; if (ptrr = (chhar *)mmallloc(0) = NUULL) puts(Goot aa nuull poiinteer); else puts(Goot aa vaalidd poointter); 这是一个有有趣的问问题。最最近在我我的一个个同事不不经意把把0值传传给了函函
29、数maallooc,得得到了一一个合法法的指针针之后,我我才想到到这个问问题。这这就是上上面的代代码,该该代码的的输出是是Goot aa vaalidd poointter。我用用这个来来开始讨讨论这样样的一问问题,看看看被面面试者是是否想到到库例程程这样做做是正确确。得到到正确的的答案固固然重要要,但解解决问题题的方法法和你做做决定的的基本原原理更重重要些。 Typeddef 一五 Tyypeddef 在C语语言中频频繁用以以声明一一个已经经存在的的数据类类型的同同义字。也也可以用用预处理理器做类类似的事事。例如如,思考考一下下下面的例例子: #defiine dPSS sttrucct ss * typeddef strructt s * ttPS; 以上两种情情况的意意图都是是要定义义d
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑工人解除劳动合同协议
- 知识产权保险公司合同盖章指南
- 体育行业员工待岗协议
- 电视台公关部聘用合同
- 城市广场喷泉施工合同
- 供水管道铺设合同完整版
- 医疗机构二手房交易合同模板
- 医疗器械销售顾问招聘合同
- 油气管道铺设专业施工合同范本
- 农业科技园合同履约监管案例
- 2024-2025学年上海市普陀区八年级(上)期中数学试卷
- 假期补课协议书
- 电子商务支付结算系统开发合同
- 服务质量、保证措施
- (必练)广东省军队文职(经济学)近年考试真题试题库(含答案)
- 含羞草天气课件
- 2024年安全生产知识竞赛考试题库及答案(共五套)
- 22《鸟的天堂》课件
- 农业灌溉装置市场环境与对策分析
- 新疆乌鲁木齐市第十一中学2024-2025学年八年级上学期期中道德与法治试卷
- 2024年江西省高考地理真题(原卷版)
评论
0/150
提交评论