C语言终极面试宝典 C语言面试必备_第1页
C语言终极面试宝典 C语言面试必备_第2页
C语言终极面试宝典 C语言面试必备_第3页
C语言终极面试宝典 C语言面试必备_第4页
C语言终极面试宝典 C语言面试必备_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第一部分分:基本本概念及及其它问问答题1、关键键字sttatiic的作作用是什什么?这个简单单的问题题很少有有人能回回答完全全。在CC语言中中,关键键字sttatiic有三三个明显显的作用用:1). 在函数数体,一一个被声声明为静静态的变变量在这这一函数数被调用用过程中中维持其其值不变变。2). 在模块块内(但但在函数数体外),一一个被声声明为静静态的变变量可以以被模块块内所用用函数访访问,但但不能被被模块外外其它函函数访问问。它是是一个本本地的全全局变量量。3). 在模块块内,一一个被声声明为静静态的函函数只可可被这一一模块内内的其它它函数调调用。那那就是,这这个函数数被限制制在声明明它的模

2、模块的本本地范围围内使用用。大多数应应试者能能正确回回答第一一部分,一一部分能能正确回回答第二二部分,同同是很少少的人能能懂得第第三部分分。这是是一个应应试者的的严重的的缺点,因因为他显显然不懂懂得本地地化数据和代码码范围的的好处和和重要性性。2、“引引用”与指针针的区别别是什么么?答、1) 引用用必须被被初始化化,指针针不必。2) 引引用初始始化以后后不能被被改变,指指针可以以改变所所指的对对象。3) 不不存在指指向空值值的引用用,但是是存在指指向空值值的指针针。指针通过过某个指指针变量量指向一一个对象象后,对对它所指指向的变变量间接接操作。程序中中使用指指针,程程序的可可读性差差;而引引用

3、本身身就是目目标变量量的别名名,对引引用的操操作就是是对目标标变量的的操作。流操作符符、赋赋值操作作符=的返回回值、拷拷贝构造造函数的的参数、赋值操操作符=的参数数、其它它情况都都推荐使使用引用用3、.hh头文件件中的iifnddef/deffinee/enndiff 的作作用?答:防止止该头文文件被重重复引用用。4、#iinclludee 与#inncluude fiile.h的的区别?答:前者者是从SStanndarrd LLibrraryy的路径径寻找和和引用ffilee.h,而而后者是是从当前前工作路路径搜寻寻并引用用fille.hh。5、描述述实时系系统的基基本特性性答:在特特定时间

4、间内完成成特定的的任务,实实时性与与可靠性性。6、全局局变量和和局部变变量在内内存中是是否有区区别?如如果有,是是什么区区别?答:全局局变量储储存在静静态数据据区,局局部变量量在堆栈栈中。7、什么么是平衡衡二叉树树?答:左右右子树都都是平衡衡二叉树树且左右右子树的的深度差差值的绝绝对值不不大于11。8、堆栈栈溢出一一般是由由什么原原因导致致的?答:1.没有回回收垃圾圾资源 2.层次太太深的递递归调用用9、冒泡泡排序算算法的时时间复杂杂度是什什么?答:O(n22)10、什什么函数数不能声声明为虚虚函数?答:coonsttrucctorr11、队队列和栈栈有什么么区别?答:队列列先进先先出,栈栈后

5、进先先出12、不不能做sswittch()的参参数类型型答:swwitcch的参参数不能能为实型型。13、局局部变量量能否和和全局变变量重名名?答:能,局局部会屏屏蔽全局局。要用用全局变变量,需需要使用用:局部变量量可以与与全局变变量同名名,在函函数内引引用这个个变量时时,会用用到同名名的局部部变量,而而不会用用到全局局变量。对于有有些编译译器而言言,在同同一个函函数内可可以定义义多个同同名的局局部变量量,比如如在两个个循环体体内都定定义一个个同名的的局部变变量,而而那个局局部变量量的作用用域就在在那个循循环体内内14、如如何引用用一个已已经定义义过的全全局变量量?答、可以以用引用用头文件件的

6、方式式,也可可以用eexteern关关键字,如如果用引引用头文文件方式式来引用用某个在在头文件件中声明明的全局局变量,假假定你将将那个变变量写错错了,那那么在编编译期间间会报错错,如果果你用eexteern方方式引用用时,假假定你犯犯了同样样的错误误,那么么在编译译期间不不会报错错,而在在连接期期间报错错。15、全全局变量量可不可可以定义义在可被被多个.C文件件包含的的头文件件中?为为什么?答、可以以,在不不同的CC文件中中以sttatiic形式式来声明明同名全全局变量量。可以在不不同的CC文件中中声明同同名的全全局变量量,前提提是其中中只能有有一个CC文件中中对此变变量赋初初值,此此时连接接

7、不会出出错。16、语语句foor( ;1 ;)有什么么问题?它是什什么意思思?答、和wwhille(11)相同同,无限限循环。17、ddowhiile和和whiiledoo有什么么区别?答、前一一个循环环一遍再再判断,后后一个判判断以后后再循环环。18、sstattac 全局变变量、局局部变量量、函数数与普通通全局变变量、局局部变量量、函数数stattic全全局变量量与普通通的全局局变量有有什么区区别?sstattic局局部变量量和普通通局部变变量有什什么区别别?sttatiic函数数与普通通函数有有什么区区别?答、全局局变量(外部变变量)的说明明之前再再冠以sstattic 就构成成了静态态

8、的全局局变量。全局变变量本身身就是静静态存储储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。从以上分分析可以以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使

9、用范围。stattic函函数与普普通函数数作用域域不同。仅在本本文件。只在当当前源文文件中使使用的函函数应该该说明为为内部函函数(sstattic),内部部函数应应该在当当前源文文件中说说明和定定义。对对于可在在当前源源文件以以外使用用的函数数,应该该在一个个头文件件中说明明,要使使用这些些函数的的源文件件要包含含这个头头文件stattic全全局变量量与普通通的全局局变量有有什么区区别:sstattic全全局变量量只初使使化一次次,防止止在其他他文件单单元中被被引用;stattic局局部变量量和普通通局部变变量有什什么区别别:sttatiic局部部变量只只被初始始化一次次,下一一次依据据上一次

10、次结果值值;stattic函函数与普普通函数数有什么么区别:staaticc函数在在内存中中只有一一份,普普通函数数在每个个被调用用中维持持一份拷拷贝19、程程序的内内存分配配答:一一个由cc/C+编译译的程序序占用的的内存分分为以下下几个部部分1、栈区区(sttackk)由编译译器自动动分配释释放,存存放函数数的参数数值,局局部变量量的值等等。其操操作方式式类似于于数据结结构中的的栈。22、堆区区(heeap)一般由由程序员员分配释释放,若若程序员员不释放放,程序序结束时时可能由由OS回收收。注意意它与数数据结构构中的堆堆是两回回事,分分配方式式倒是类类似于链链表,呵呵呵。33、全局局区(静

11、静态区)(static)全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。4、文字常量区常量字符串就是放在这里的。程序结束后由系统释放。5、程序代码区存放函数体的二进制代码例子程序序这是一一个前辈辈写的,非非常详细细/mmainn.cppp intt a=0; /全全局初始始化区 chhar *p11; /全局未未初始化化区 maiin() inttb;栈栈 chaar ss=abbc; /栈栈 chaar *p2; /栈栈 chaar *p3=12234556; /112344560在常

12、常量区,pp3在栈栈上。 sstattic intt c=0; /全局局(静态态)初始始化区 pp1 = (ccharr*)mmallloc(10); p22 = (chhar*)maallooc(220); /分分配得来来得100和200字节的的区域就就在堆区区。 sttrcppy(pp1,12334566); /112344560放在在常量区区,编译译器可能能会将它它与p33所向12334566优化化成一个个地方。20、解解释堆和和栈的区区别答:堆(hheapp)和栈栈(sttackk)的区区别(1)申申请方式式staack:由系统统自动分分配。例例如,声声明在函函数中一一个局部部变量ii

13、nt b;系系统自动动在栈中中为b开开辟空间间heaap:需需要程序序员自己己申请,并并指明大大小,在在c中mmallloc函函数如pp1=(chaar*)malllocc(100);在在C+中用nnew运运算符如如p2=(chhar*)maallooc(110);但是注注意p11、p22本身是是在栈中中的。(2)申申请后系系统的响响应栈:只要栈栈的剩余余空间大大于所申申请空间间,系统统将为程程序提供供内存,否否则将报报异常提提示栈溢溢出。堆堆:首先先应该知知道操作作系统有有一个记记录空闲闲内存地地址的链链表,当当系统收收到程序序的申请请时,会会遍历该该链表,寻寻找第一一个空间间大于所所申请空

14、空间的堆堆结点,然然后将该该结点从从空闲结结点链表表中删除除,并将将该结点点的空间间分配给给程序,另另外,对对于大多多数系统统,会在在这块内内存空间间中的首首地址处处记录本本次分配配的大小小,这样样,代码码中的ddeleete语语句才能能正确的的释放本本内存空空间。另另外,由由于找到到的堆结结点的大大小不一一定正好好等于申申请的大大小,系系统会自自动的将将多余的的那部分分重新放放入空闲闲链表中中。(3)申申请大小小的限制制栈:在在Winndowws下,栈是向向低地址址扩展的的数据结结构,是是一块连连续的内内存的区区域。这这句话的的意思是是栈顶的的地址和和栈的最最大容量量是系统统预先规规定好的的

15、,在WWINDDOWSS下,栈栈的大小小是2MM(也有有的说是是1M,总总之是一一个编译译时就确确定的常常数),如如果申请请的空间间超过栈栈的剩余余空间时时,将提提示ovverffloww。因此此,能从从栈获得得的空间间较小。堆:堆堆是向高高地址扩扩展的数数据结构构,是不不连续的的内存区区域。这这是由于于系统是是用链表表来存储储的空闲闲内存地地址的,自自然是不不连续的的,而链链表的遍遍历方向向是由低低地址向向高地址址。堆的的大小受受限于计计算机系系统中有有效的虚虚拟内存存。由此此可见,堆堆获得的的空间比比较灵活活,也比比较大。(4)申申请效率率的比较较:栈:由系统统自动分分配,速速度较快快。但

16、程程序员是是无法控控制的。堆:是是由neew分配配的内存存,一般般速度比比较慢,而而且容易易产生内内存碎片片,不过过用起来来最方便便.另外外,在WWINDDOWSS下,最最好的方方式是用用Virrtuaal AAllooc分配配内存,他他不是在在堆,也也不是在在栈,而而是直接接在进程程的地址址空间中中保留一一块内存存,虽然然用起来来最不方方便。但但是速度度快,也也最灵活活。(5)堆堆和栈中中的存储储内容栈栈:在函函数调用用时,第第一个进进栈的是是主函数数中后的的下一条条指令(函函数调用用语句的的下一条条可执行行语句)的的地址,然然后是函函数的各各个参数数,在大大多数的的C编译译器中,参参数是由

17、由右往左左入栈的的,然后后是函数数中的局局部变量量。注意意静态变变量是不不入栈的的。当本本次函数数调用结结束后,局局部变量量先出栈栈,然后后是参数数,最后后栈顶指指针指向向最开始始存的地地址,也也就是主主函数中中的下一一条指令令,程序序由该点点继续运运行。堆堆:一般般是在堆堆的头部部用一个个字节存存放堆的的大小。堆中的的具体内内容由程程序员安安排。(6)存存取效率率的比较较charr s11=aaaaaaaaaaaaaaaaaaaa;chaar *s2=bbbbbbbbbbbbbbbbbbbbbbb;aaaaaaaaaaaaaaa是在在运行时时刻赋值值的;而而bbbbbbbbbbbbbb是是在

18、编译译时就确确定的;但是,在在以后的的存取中中,在栈栈上的数数组比指指针所指指向的字字符串(例如堆堆)快。比如:#inncluudevvoiddmaiin()chaar aa=1;chaar cc=1223455678890;chhar *p=1223455678890;a = cc1;a = pp1;reeturrn;对应的的汇编代代码100:a=c11;000400106678AA4DFF1moovcll,byytepptrebpp-0FFh0004001066A8884DFFCmoovbyytepptrebpp-4,cll11:a=pp1;000401106DD8B555ECCmovve

19、dxx,dwworddptrrebbp-114h004401007088A42201mmovaal,bbyteeptrreddx+110004011073388445FCCmovvbyttepttreebp-4,al第第一种在在读取时时直接就就把字符符串中的的元素读读到寄存存器cll中,而而第二种种则要先先把指针针值读到到edxx中,在在根据eedx读读取字符符,显然然慢了。21、什什么是预预编译,何时需需要预编编译?答:预编编译又称称为预处处理,是是做些代代码文本本的替换换工作。处理#开头的的指令,比如拷拷贝#iinclludee包含的的文件代代码,#deffinee宏定义义的替换换,条件件

20、编译等等,就是是为编译译做的预预备工作作的阶段段,主要要处理#开始的的预编译译指令,预预编译指指令指示示了在程程序正式式编译前前就由编编译器进进行的操操作,可可以放在在程序中中的任何何位置。c编译系系统在对对程序进进行通常常的编译译之前,先先进行预预处理。c提供供的预处处理功能能主要有有以下三三种:11)宏定定义22)文件件包含3)条条件编译译总是使用用不经常常改动的的大型代代码体。、程序序由多个个模块组组成,所所有模块块都使用用一组标标准的包包含文件件和相同同的编译译选项。在这种种情况下下,可以以将所有有包含文文件预编编译为一一个预编编译头。22、关关键字cconsst是什什么含意意?答:我

21、只只要一听听到被面面试者说说:“cconsst意味味着常数数”,我我就知道道我正在在和一个个业余者者打交道道。去年年Dann Saaks已已经在他他的文章章里完全全概括了了connst的的所有用用法,因因此ESSP(译译者:EEmbeeddeed SSysttemss Prrogrrammmingg)的每每一位读读者应该该非常熟熟悉coonstt能做什什么和不不能做什什么.如如果你从从没有读读到那篇篇文章,只只要能说说出coonstt意味着着“只读读”就可可以了。尽管这这个答案案不是完完全的答答案,但但我接受受它作为为一个正正确的答答案。(如如果你想想知道更更详细的的答案,仔仔细读一一下Saa

22、ks的的文章吧吧。)如如果应试试者能正正确回答答这个问问题,我我将问他他一个附附加的问问题:下下面的声声明都是是什么意意思?consst iint a;int connst a;consst iint *a;int * cconsst aa;int connst * aa coonstt;前两个的的作用是是一样,aa是一个个常整型型数。第第三个意意味着aa是一个个指向常常整型数数的指针针(也就就是,整整型数是是不可修修改的,但但指针可可以)。第四个个意思aa是一个个指向整整型数的的常指针针(也就就是说,指指针指向向的整型型数是可可以修改改的,但但指针是是不可修修改的)。最后一一个意味味着a是是

23、一个指指向常整整型数的的常指针针(也就就是说,指指针指向向的整型型数是不不可修改改的,同同时指针针也是不不可修改改的)。如果应应试者能能正确回回答这些些问题,那那么他就就给我留留下了一一个好印印象。顺顺带提一一句,也也许你可可能会问问,即使使不用关关键字 connst,也也还是能能很容易易写出功功能正确确的程序序,那么么我为什什么还要要如此看看重关键键字coonstt呢?我我也如下下的几下下理由:1). 关键字字connst的的作用是是为给读读你代码码的人传传达非常常有用的的信息,实实际上,声声明一个个参数为为常量是是为了告告诉了用用户这个个参数的的应用目目的。如如果你曾曾花很多多时间清清理其

24、它它人留下下的垃圾圾,你就就会很快快学会感感谢这点点多余的的信息。(当然然,懂得得用coonstt的程序序员很少少会留下下的垃圾圾让别人人来清理理的。)2). 通过给给优化器器一些附附加的信信息,使使用关键键字coonstt也许能能产生更更紧凑的的代码。3). 合理地地使用关关键字cconsst可以以使编译译器很自自然地保保护那些些不希望望被改变变的参数数,防止止其被无无意的代代码修改改。简而而言之,这这样可以以减少bbug的的出现23、关关键字vvolaatille有什什么含意意 并给给出三个个不同的的例子。答:一个个定义为为vollatiile的的变量是是说这变变量可能能会被意意想不到到地

25、改变变,这样样,编译译器就不不会去假假设这个个变量的的值了。精确地地说就是是,优化化器在用用到这个个变量时时必须每每次都小小心地重重新读取取这个变变量的值值,而不不是使用用保存在在寄存器器里的备备份。下下面是vvolaatille变量量的几个个例子:1). 并行设设备的硬硬件寄存存器(如如:状态态寄存器器)2). 一个中中断服务务子程序序中会访访问到的的非自动动变量(Nonn-auutommatiic vvariiablles)3). 多线程程应用中中被几个个任务共共享的变变量回答不出出这个问问题的人人是不会会被雇佣佣的。我我认为这这是区分分C程序序员和嵌嵌入式系系统程序序员的最最基本的的问题

26、。嵌入式式系统程程序员经经常同硬硬件、中中断、RRTOSS等等打打交道,所所用这些些都要求求vollatiile变变量。不不懂得vvolaatille内容容将会带带来灾难难。假设被面面试者正正确地回回答了这这是问题题(嗯,怀怀疑这否否会是这这样),我我将稍微微深究一一下,看看一下这这家伙是是不是直直正懂得得vollatiile完完全的重重要性。1). 一个参参数既可可以是cconsst还可可以是vvolaatille吗?解释为为什么。2). 一个指指针可以以是voolattilee 吗?解释为为什么。3). 下面的的函数有有什么错错误:int squuaree(voolattilee innt

27、 *ptrr)retuurn *pttr * *pptr;下面是答答案:1). 是的。一个例例子是只只读的状状态寄存存器。它它是voolattilee因为它它可能被被意想不不到地改改变。它它是coonstt因为程程序不应应该试图图去修改改它。2). 是的。尽管这这并不很很常见。一个例例子是当当一个中中服务子子程序修修该一个个指向一一个buuffeer的指指针时。3). 这段代代码的有有个恶作作剧。这这段代码码的目的的是用来来返指针针*pttr指向向值的平平方,但但是,由由于*pptr指指向一个个vollatiile型型参数,编编译器将将产生类类似下面面的代码码:int squuaree(voo

28、lattilee innt *ptrr)int a,bb;a = *pttr;b = *pttr;retuurn a * b;由于*pptr的的值可能能被意想想不到地地该变,因因此a和和b可能能是不同同的。结结果,这这段代码码可能返返不是你你所期望望的平方方值!正正确的代代码如下下:longg sqquarre(vvolaatille iint *pttr)int a;a = *pttr;retuurn a * a;24、三三种基本本的数据据模型答:按照照数据结结构类型型的不同同,将数数据模型型划分为为层次模模型、网网状模型型和关系系模型。25、结结构与联联合有和和区别?答:(11). 结构和

29、和联合都都是由多多个不同同的数据据类型成成员组成成, 但但在任何何同一时时刻, 联合中中只存放放了一个个被选中中的成员员(所有有成员共共用一块块地址空空间), 而结结构的所所有成员员都存在在(不同同成员的的存放地地址不同同)。(22). 对于联联合的不不同成员员赋值, 将会会对其它它成员重重写,原来成成员的值值就不存存在了, 而对对于结构构的不同同成员赋赋值是互互不影响响的26、描描述内存存分配方方式以及及它们的的区别?答:1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。2) 在栈上创建。在执行函数时,函数内局部

30、变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多27、请请说出cconsst与#deffinee 相比比,有何何优点?答:Coonstt作用:定义常常量、修修饰函数数参数、修饰函函数返回回值三个个作用。被Coonstt修饰的的东西都都受到强强制保护护,可以以预防意意外的变变动,能能提高程程序的健健壮性。1) cconsst 常常

31、量有数数据类型型,而宏宏常量没没有数据据类型。编译器器可以对对前者进进行类型型安全检检查。而而对后者者只进行行字符替替换,没没有类型型安全检检查,并并且在字字符替换换可能会会产生意意料不到到的错误误。 2) 有些集集成化的的调试工工具可以以对coonstt 常量量进行调调试,但但是不能能对宏常常量进行行调试。28、简简述数组组与指针针的区别别?答:数组组要么在在静态存存储区被被创建(如如全局数数组),要要么在栈栈上被创创建。指指针可以以随时指指向任意意类型的的内存块块。 (1)修修改内容容上的差差别 chhar a = “heelloo”; aa0 = X; chhar *p = “wworl

32、ld”; / 注意意p 指指向常量量字符串串 p00 = XX; / 编译器器不能发发现该错错误,运运行时错错误 (22) 用用运算符符sizzeoff 可以以计算出出数组的的容量(字字节数)。sizzeoff(p),p 为指针针得到的的是一个个 指针针变量的的字节数数,而不不是p 所指的的内存容容量。CC+/C 语语言没有有办法知知道指针针所指的的内存容容量,除除非在申申请内存存时记住住它。注注意当数数组作为为函数的的参数进进行传递递时,该该数组自自动退化化为同类类型的指指针。 chhar a = heelloo woorldd; chhar *p = aa; couut siizeoof(

33、aa) eendll; / 112 字字节 couut siizeoof(pp) eendll; / 44 字节节 计计算数组组和指针针的内存存容量 vooid Funnc(ccharr a1000) ccoutt sizzeoff(a) enndl; / 4 字节而而不是1100 字节 29、分分别写出出BOOOL,iint,flooat,指针类类型的变变量a 与“零零”的比比较语句句。答:BOOOL : iif ( !aa ) or if(a)iint : if ( aa = 0)flooat :coonstt EXXPREESSIION EXPP = 0.00000001 if ( aa

34、 -EEXP)poiinteer : iff ( a != NNULLL) oor iif(aa = NUULL) 30、如如何判断断一段程程序是由由C 编编译程序序还是由由C+编译程程序编译译的?答:#iifdeef _cpplusspluuscooutcc+;#eelseecouutc;#eendiif31、论论述含参参数的宏宏与函数数的优缺缺点答: 带参宏宏 函数数处理时间间 编译译时 程序运运行时参数类型型 没有参参数类型型问题 定定义实参参、形参参类型处理过程程 不分配配内存 分分配内存存程序长度度 变长 不不变运行速度度 不占运运行时间间 调用用和返回回占用时时间32、用用两个栈栈

35、实现一一个队列列的功能能?要求求给出算算法和思思路!答 、设设2个栈栈为A,B, 一开始始均为空空.入队:将新元素素pussh入栈栈A;出队:(1)判判断栈BB是否为为空;(2)如如果不为为空,则则将栈AA中所有有元素依依次poop出并并pussh到栈栈B;(3)将将栈B的的栈顶元元素poop出;这样实现现的队列列入队和和出队的的平摊复复杂度都都还是OO(1), 比比上面的的几种方方法要好好33、嵌嵌入式系系统中经经常要用用到无限限循环,你你怎么样样用C编编写死循循环呢?答:这个个问题用用几个解解决方案案。我首首选的方方案是:whille(11)一些程序序员更喜喜欢如下下方案:for(;)这个

36、实现现方式让让我为难难,因为为这个语语法没有有确切表表达到底底怎么回回事。如如果一个个应试者者给出这这个作为为方案,我我将用这这个作为为一个机机会去探探究他们们这样做做的基本原理理。如果果他们的的基本答答案是:“我被被教着这这样做,但但从没有有想到过过为什么么。”这这会给我我留下一一个坏印印象。第三个方方案是用用 gootoLoopp:.gotoo Looop;应试者如如给出上上面的方方案,这这说明或或者他是是一个汇汇编语言言程序员员(这也也许是好好事)或或者他是是一个想想进入新新领域的的BASSIC/FORRTRAAN程序序员。34、位位操作(BBit mannipuulattionn) 答

37、: 嵌嵌入式系系统总是是要用户户对变量量或寄存存器进行行位操作作。给定定一个整整型变量量a,写写两段代代码,第第一个设设置a的的bitt 3,第第二个清清除a 的biit 33。在以以上两个个操作中中,要保保持其它它位不变变。对这这个问题题有三种种基本的的反应11)不知知道如何何下手。该被面面者从没没做过任任何嵌入入式系统统的工作作。2) 用bbit fieeldss。Biit ffiellds是是被扔到到C语言言死角的的东西,它它保证你你的代码码在不同同编译器器之间是是不可移移植的,同同时也保保证了的的你的代代码是不不可重用用的。我我最近不不幸看到到 Innfinneonn为其较较复杂的的通

38、信芯芯片写的的驱动程程序,它它用到了了bitt fiieldds因此此完全对对我无用用,因为为我的编编译器用用其它的的方式来来实现bbit fieeldss的。从从道德讲讲:永远远不要让让一个非非嵌入式式的家伙伙粘实际际硬件的的边。33) 用用 #ddefiiness 和 bitt maaskss 操作作。这是是一个有有极高可可移植性性的方法法,是应应该被用用到的方方法。最最佳的解解决方案案如下:#deefinne BBIT33 (00 x1 3)sstattic intt a;voiid sset_bitt3(vvoidd) a |= BITT3;voiid ccleaar_bbit33(v

39、ooid) a &= BIIT3; 一些些人喜欢欢为设置置和清除除值而定定义一个个掩码同同时定义义一些说说明常数数,这也也是可以以接受的的。我希希望看到到几个要要点:说说明常数数、|=和&=操作作。35、访访问固定定的内存存位置(AAcceessiing fixxed memmoryy loocattionns) 答:嵌入入式系统统经常具具有要求求程序员员去访问问某特定定的内存存位置的的特点。在某工工程中,要要求设置置一绝对对地址为为0 x667a99的整型型变量的的值为00 xaaa66。编译器器是一个个纯粹的的ANSSI编译译器。写写代码去去完成这这一任务务。这一一问题测测试你是是否知道道

40、为了访访问一绝绝对地址址把一个个整型数数强制转转换(ttypeecasst)为为一指针针是合法法的。这这一问题题的实现现方式随随着个人人风格不不同而不不同。典典型的类类似代码码如下: innt *ptrr; pptr = (intt *)0 x667a99; *ptrr = 0 xaaa666;AA moore obsscurre aapprroacch iis: 一个较较晦涩的的方法是是: *(innt * coonstt)(00 x677a9) = 0 xaaa555;即使使你的品品味更接接近第二二种方案案,但我我建议你你在面试试时使用用第一种种方案。36、中中断(IInteerruupt

41、ss)答: 中中断是嵌嵌入式系系统中重重要的组组成部分分,这导导致了很很多编译译开发商商提供一一种扩展展让标标准C支支持中断断。具代代表事实实是,产产生了一一个新的的关键字字 _intterrruptt。下面面的代码码就使用用了_intterrruptt关键字字去定义义了一个个中断服服务子程程序(IISR),请评评论一下下这段代代码的。_iinteerruupt douublee coompuute_areea (douublee raadiuus) dooublle aareaa = PI * rradiius * rradiius; prrinttf(nAAreaa = %f, aarea

42、a); retturnn arrea;这个函函数有太太多的错错误了,以以至让人人不知从从何说起起了:11)ISSR 不不能返回回一个值值。如果果你不懂懂这个,那那么你不不会被雇雇用的。2) ISRR 不能能传递参参数。如如果你没没有看到到这一点点,你被被雇用的的机会等等同第一一项。33) 在在许多的的处理器器/编译译器中,浮浮点一般般都是不不可重入入的。有有些处理理器/编编译器需需要让额额处的寄寄存器入入栈,有有些处理理器/编编译器就就是不允允许在IISR中中做浮点点运算。此外,IISR应应该是短短而有效效率的,在在ISRR中做浮浮点运算算是不明明智的。4) 与第三三点一脉脉相承,pprinn

43、tf()经常常有重入入和性能能上的问问题。如如果你丢丢掉了第第三和第第四点,我我不会太太为难你你的。不不用说,如如果你能能得到后后两点,那那么你的的被雇用用前景越越来越光光明了。37、动动态内存存分配(DDynaamicc meemorry aalloocattionn) 答:尽管管不像非非嵌入式式计算机机那么常常见,嵌嵌入式系系统还是是有从堆堆(heeap)中中动态分分配内存存的过程程的。那那么嵌入入式系统统中,动动态分配配内存可可能发生生的问题题是什么么?这里里,我期期望应试试者能提提到内存存碎片,碎碎片收集集的问题题,变量量的持行行时间等等等。这这个主题题已经在在ESPP杂志中中被广泛泛

44、地讨论论过了(主主要是 P.JJ. PPlauugerr, 他他的解释释远远超超过我这这里能提提到的任任何解释释),所所有回过过头看一一下这些些杂志吧吧!让应应试者进进入一种种虚假的的安全感感觉后,我我拿出这这么一个个小节目目:下面面的代码码片段的的输出是是什么,为为什么?chaar *ptrr;iff (ptrr = (chhar *)mmallloc(0) = NUULL) pputss(GGot a nnulll poointter);eelsee puuts(Goot aa vaalidd poointter);这这是一个个有趣的的问题。最近在在我的一一个同事事不经意意把0值值传给了了

45、函数mmallloc,得得到了一一个合法法的指针针之后,我我才想到到这个问问题。这这就是上上面的代代码,该该代码的的输出是是Goot aa vaalidd poointter。我用用这个来来开始讨讨论这样样的一问问题,看看看被面面试者是是否想到到库例程程这样做做是正确确。得到到正确的的答案固固然重要要,但解解决问题题的方法法和你做做决定的的基本原原理更重重要些。38、TTypeedeff 答:Tyypeddef 在C语语言中频频繁用以以声明一一个已经经存在的的数据类类型的同同义字。也可以以用预处处理器做做类似的的事。例例如,思思考一下下下面的的例子:#deefinne ddPS strruct

46、t s *tyypeddef strructt s * ttPS; 以上两两种情况况的意图图都是要要定义ddPS 和 ttPS 作为一一个指向向结构ss指针。哪种方方法更好好呢?(如如果有的的话)为为什么? 这是一一个非常常微妙的的问题,任任何人答答对这个个问题(正正当的原原因)是是应当被被恭喜的的。答案案是:ttypeedeff更好。思考下下面的例例子:ddPS p1,p2;tPSS p33,p44;第一一个扩展展为sttrucct ss * p1, p22; 上上面的代代码定义义p1为为一个指指向结构构的指,pp2为一一个实际际的结构构,这也也许不是是你想要要的。第第二个例例子正确确地定义

47、义了p33 和pp4 两两个指针针。39、用用变量aa给出下下面的定定义答:a) 一个个整型数数(Ann inntegger)b) 一一个指向向整型数数的指针针(A poiinteer tto aan iinteegerr)c) 一一个指向向指针的的的指针针,它指指向的指指针是指指向一个个整型数数(A poiinteer tto aa poointter to an inttegeer)d) 一一个有110个整整型数的的数组(AAn aarraay oof 110 iinteegerrs)e) 一一个有110个指指针的数数组,该该指针是是指向一一个整型型数的(AAn aarraay oof 1

48、10 ppoinnterrs tto iinteegerrs)f) 一一个指向向有100个整型型数数组组的指针针(A poiinteer tto aan aarraay oof 110 iinteegerrs)g) 一一个指向向函数的的指针,该该函数有有一个整整型参数数并返回回一个整整型数(AA poointter to a ffuncctioon tthatt taakess ann inntegger as an arggumeent andd reeturrns an inttegeer)h) 一一个有110个指指针的数数组,该该指针指指向一个个函数,该该函数有有一个整整型参数数并返回回

49、一个整整型数( An arrray of tenn poointterss too fuuncttionns tthatt taake an inttegeerarguumennt aand retturnn ann inntegger )答案是:a) iint a; / An inttegeerb) iint *a; / A poiinteer tto aan iinteegerrc) iint *aa; / AA poointter to a ppoinnterr too ann innteggerd) iint a110; / Ann arrrayy off 100 innteggers

50、se) iint *a10; / AAn aarraay oof 110 ppoinnterrs tto iinteegerrsf) iint (*aa)110; / A poiinteer tto aan aarraay oof 110 iinteegerrsg) iint (*aa)(iint); / AA poointter to a ffuncctioon aa thhat takkes an inttegeer aarguumennt aand retturnns aan iinteegerrh) iint (*aa100)(intt); / An arrray of 10 poii

51、nteers to funnctiionss thhat takke aan iinteegerr arrgummentt annd rretuurn an inttegeer40、解解释局部部变量、全局变变量和静静态变量量的含义义。答:41、写写一个“标标准”宏宏答:交换换两个参参数值的的宏定义义为:. #ddefiine SWAAP(aa,b) (a)=(aa)+(b);(b)=(a)-(bb);(a)=(a)-(bb);输入两个个参数,输输出较小小的一个个:#ddefiine MINN(A,B) (AA) nnextt,并随随后删除除原neext指指向的节节点。第二部分分:程序序代码评评

52、价或者者找错1、下面面的代码码输出是是什么,为为什么?voiid ffoo(voiid) unnsiggnedd innt aa = 6; intt b = -20; (aa+b 66) ? puuts( 6) : putts(66。原原因是当当表达式式中存在在有符号号类型和和无符号号类型时时所有的的操作数数都自动动转换为为无符号号类型。因此-20变变成了一一个非常常大的正正整数,所所以该表表达式计计算出的的结果大大于6。这一点点对于应应当频繁繁用到无无符号数数据类型型的嵌入入式系统统来说是是丰常重重要的。如果你你答错了了这个问问题,你你也就到到了得不不到这份份工作的的边缘。2、评评价下面面的

53、代码码片断:unssignned intt zeero = 00;unnsiggnedd innt ccomppzerro = 0 xxFFFFF; /*11s commpleemennt oof zzeroo */对于一一个innt型不不是166位的处处理器为为说,上上面的代代码是不不正确的的。应编编写如下下:unnsiggnedd innt ccomppzerro = 00;这一一问题真真正能揭揭露出应应试者是是否懂得得处理器器字长的的重要性性。在我我的经验验里,好好的嵌入入式程序序员非常常准确地地明白硬硬件的细细节和它它的局限限,然而而PC机机程序往往往把硬硬件作为为一个无无法避免免的烦

54、恼恼。3、 CC语言同同意一些些令人震震惊的结结构,下下面的结结构是合合法的吗吗,如果果是它做做些什么么?innt aa = 5, b = 7, c;c = a+bb;这个个问题将将做为这这个测验验的一个个愉快的的结尾。不管你你相不相相信,上上面的例例子是完完全合乎乎语法的的。问题题是编译译器如何何处理它它?水平平不高的的编译作作者实际际上会争争论这个个问题,根根据最处处理原则则,编译译器应当当能处理理尽可能能所有合合法的用用法。因因此,上上面的代代码被处处理成:c = a+ + b;因此, 这段段代码持持行后aa = 6, b = 7, c = 112。如如果你知知道答案案,或猜猜出正确确答

55、案,做做得好。如果你你不知道道答案,我我也不把把这个当当作问题题。我发发现这个个问题的的最大好好处是这这是一个个关于代代码编写写风格,代代码的可可读性,代代码的可可修改性性的好的的话题。4、设有有以下说说明和定定义:typeedeff unnionn llongg i; innt kk5; ccharr c; DDATEE;struuct datta innt ccat; DAATE coww; ddoubble dogg; tooo;DATEE maax;则语句 priintff(%d,sizzeoff(sttrucct ddatee)+ssizeeof(maxx);的执行行结果是是? 答

56、、结结果是:52。DATTE是一一个unnionn, 变变量公用用空间. 里面面最大的的变量类类型是iint5, 占用用20个个字节. 所以以它的大大小是220dataa是一个个strructt, 每每个变量量分开占占用空间间. 依依次为iint44 + DATTE200 + douublee8 = 322.所以结果果是 220 + 322 = 52.当然.在某某些166位编辑辑器下, innt可能能是2字字节,那那么结果果是 iint22 + DATTE100 + douublee8 = 2005、请写写出下列列代码的的输出内内容#inccluddemainn()int a,bb,c,d;a

57、=100;b=a+;c=+a;d=100*a+;prinntf(b,cc,d:%d,%d,%d,bb,c,dd);retuurn 0; 答:100,122,12206、写出出下列代代码的输输出内容容#inccluddeint incc(innt aa)retuurn(+aa);int mullti(intt*a,intt*b,intt*c)retuurn(*c=*a*b);typeedeff innt(FFUNCC1)(intt inn);typeedeff innt(FFUNCC2) (innt*,intt*,iint*);voidd shhow(FUNNC2 funn,innt aarg1

58、1, iint*argg2)INCpp=&iinc;int temmp =p(aarg11);fun(&teemp,&arrg1, arrg2);prinntf(%ddn,*aarg22);mainn()int a;showw(muultii,100,&aa);retuurn 0;答:11107、请找找出下面面代码中中的所以以错误说明:以以下代码码是把一一个字符符串倒序序,如“aabcdd”倒序序后变为为“dccba”1、#iinclludeesttrinng.hh2、maain()3、4、 ccharr*srrc=helllo,worrld;5、 ccharr* ddestt=NUULL;6

59、、 iint lenn=sttrleen(ssrc);7、 ddestt=(ccharr*)mmallloc(lenn);8、 ccharr* dd=deest;9、 ccharr* ss=srrcllen;10、 whiile(lenn-!=0) 11、 d+=s-;12、 priintff(%s,desst);13、 retturnn 0;14、答:方法1:int maiin()charr* ssrc = helllo,worrld;int lenn = strrlenn(srrc);charr* ddestt = (chhar*)maallooc(llen+1);/要要为00分配一一个空

60、间间charr* dd = desst;charr* ss = &srrcllen-1;/指指向最后后一个字字符whille( lenn- != 0 )*d+=*ss-;*d = 0;/尾尾部要加加0prinntf(%ssn,deest);freee(deest);/ 使用用完,应应当释放放空间,以以免造成成内存汇汇泄露retuurn 0;方法2:#inccludde #inccludde mainn()charr sttr=hhelllo,wworlld;int lenn=sttrleen(sstr);charr t;for(intt i=0; illen/2; i+)t=sttrii; s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论