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

下载本文档

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

文档简介

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

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

3、作就就是对目目标变量量的操作作。流操作符、赋赋值操作作符=的返回回值、拷拷贝构造造函数的的参数、赋赋值操作作符=的参数数、其它它情况都都推荐使使用引用用3、.h头头文件中中的iffndeef/ddefiine/enddif 的作用用?答:防止该该头文件件被重复复引用。4、#inncluude 与与#inncluude fiile.h的的区别?答:前者是是从Sttanddardd Liibraary的的路径寻寻找和引引用fiile.h,而而后者是是从当前前工作路路径搜寻寻并引用用fille.hh。5、描述实实时系统统的基本本特性答:在特定定时间内内完成特特定的任任务,实实时性与与可靠性性。6、全

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

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

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

7、什么意思思?答、和whhilee(1)相同,无无限循环环。17、doowwhille和whiiledoo有什么么区别?答、前一个个循环一一遍再判判断,后后一个判判断以后后再循环环。18、sttataac 全全局变量量、局部部变量、函函数与普普通全局局变量、局局部变量量、函数数statiic全局局变量与与普通的的全局变变量有什什么区别别?sttatiic局部部变量和和普通局局部变量量有什么么区别?staaticc函数与与普通函函数有什什么区别别?答、全局变变量(外部变变量)的说明明之前再再冠以sstattic 就构成成了静态态的全局局变量。全全局变量量本身就就是静态态存储方方式,静静态全局局变量

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

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

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

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

12、3=12234556; /112344560在常常量区,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)申请请方式sstacck:由由系统自自动分

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

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

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

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

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

18、以后的的存取中中,在栈栈上的数数组比指指针所指指向的字字符串(例如堆堆)快。比如:#includevoidmain()char a=1;char c=1234567890;char *p=1234567890;a = c1;a = p1;return;对应的汇编代码10:a=c1;004010678A4DF1movcl,byteptrebp-0Fh0040106A884DFCmovbyteptrebp-4,cl11:a=p1;0040106D8B55ECmovedx,dwordptrebp-14h004010708A4201moval,byteptredx+1004010738845FCmov

19、byteptrebp-4,al第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。21、什么么是预编编译,何何时需要要预编译译?答:预编译译又称为为预处理理,是做做些代码码文本的的替换工工作。处处理#开开头的指指令,比比如拷贝贝#inncluude包包含的文文件代码码,#ddefiine宏宏定义的的替换,条件编编译等,就就是为编编译做的的预备工工作的阶阶段,主主要处理理#开始始的预编编译指令令,预编编译指令令指示了了在程序序正式编编译前就就由编译译器进行行的操作作,可以以放在程程序中的的任何位位置。c编译系统统在对程程序进行

20、行通常的的编译之之前,先先进行预预处理。cc提供的的预处理理功能主主要有以以下三种种:1)宏宏定义2)文文件包含含3)条条件编译译总是使用不不经常改改动的大大型代码码体。、程序由由多个模模块组成成,所有有模块都都使用一一组标准准的包含含文件和和相同的的编译选选项。在在这种情情况下,可可以将所所有包含含文件预预编译为为一个预预编译头头。22、关键键字coonstt是什么么含意?答:我只要要一听到到被面试试者说:“coonstt意味着着常数”,我我就知道道我正在在和一个个业余者者打交道道。去年年Dann Saaks已已经在他他的文章章里完全全概括了了connst的的所有用用法,因因此ESSP(译译

21、者:EEmbeeddeed SSysttemss Prrogrrammmingg)的每每一位读读者应该该非常熟熟悉coonstt能做什什么和不不能做什什么.如如果你从从没有读读到那篇篇文章,只只要能说说出coonstt意味着着“只读读”就可可以了。尽尽管这个个答案不不是完全全的答案案,但我我接受它它作为一一个正确确的答案案。(如如果你想想知道更更详细的的答案,仔仔细读一一下Saaks的的文章吧吧。)如如果应试试者能正正确回答答这个问问题,我我将问他他一个附附加的问问题:下下面的声声明都是是什么意意思?constt innt aa;int cconsst aa;constt innt *a;in

22、t * coonstt a;int cconsst * a connst;前两个的作作用是一一样,aa是一个个常整型型数。第第三个意意味着aa是一个个指向常常整型数数的指针针(也就就是,整整型数是是不可修修改的,但但指针可可以)。第第四个意意思a是是一个指指向整型型数的常常指针(也也就是说说,指针针指向的的整型数数是可以以修改的的,但指指针是不不可修改改的)。最最后一个个意味着着a是一一个指向向常整型型数的常常指针(也也就是说说,指针针指向的的整型数数是不可可修改的的,同时时指针也也是不可可修改的的)。如如果应试试者能正正确回答答这些问问题,那那么他就就给我留留下了一一个好印印象。顺顺带提一一

23、句,也也许你可可能会问问,即使使不用关关键字 connst,也也还是能能很容易易写出功功能正确确的程序序,那么么我为什什么还要要如此看看重关键键字coonstt呢?我我也如下下的几下下理由:1). 关关键字cconsst的作作用是为为给读你你代码的的人传达达非常有有用的信信息,实实际上,声声明一个个参数为为常量是是为了告告诉了用用户这个个参数的的应用目目的。如如果你曾曾花很多多时间清清理其它它人留下下的垃圾圾,你就就会很快快学会感感谢这点点多余的的信息。(当当然,懂懂得用cconsst的程程序员很很少会留留下的垃垃圾让别别人来清清理的。)2). 通通过给优优化器一一些附加加的信息息,使用用关键

24、字字connst也也许能产产生更紧紧凑的代代码。3). 合合理地使使用关键键字coonstt可以使使编译器器很自然然地保护护那些不不希望被被改变的的参数,防防止其被被无意的的代码修修改。简简而言之之,这样样可以减减少buug的出出现23、关键键字voolattilee有什么么含意 并给出出三个不不同的例例子。答:一个定定义为vvolaatille的变变量是说说这变量量可能会会被意想想不到地地改变,这这样,编编译器就就不会去去假设这这个变量量的值了了。精确确地说就就是,优优化器在在用到这这个变量量时必须须每次都都小心地地重新读读取这个个变量的的值,而而不是使使用保存存在寄存存器里的的备份。下下面

25、是vvolaatille变量量的几个个例子:1). 并并行设备备的硬件件寄存器器(如:状态寄寄存器)2). 一一个中断断服务子子程序中中会访问问到的非非自动变变量(NNon-auttomaaticc vaariaablees)3). 多多线程应应用中被被几个任任务共享享的变量量回答不出这这个问题题的人是是不会被被雇佣的的。我认认为这是是区分CC程序员员和嵌入入式系统统程序员员的最基基本的问问题。嵌嵌入式系系统程序序员经常常同硬件件、中断断、RTTOS等等等打交交道,所所用这些些都要求求vollatiile变变量。不不懂得vvolaatille内容容将会带带来灾难难。假设被面试试者正确确地回答答

26、了这是是问题(嗯嗯,怀疑疑这否会会是这样样),我我将稍微微深究一一下,看看一下这这家伙是是不是直直正懂得得vollatiile完完全的重重要性。1). 一一个参数数既可以以是coonstt还可以以是voolattilee吗?解解释为什什么。2). 一一个指针针可以是是vollatiile 吗?解解释为什什么。3). 下下面的函函数有什什么错误误:int ssquaare(vollatiile intt *pptr)returrn *ptrr * *pttr;下面是答案案:1). 是是的。一一个例子子是只读读的状态态寄存器器。它是是vollatiile因因为它可可能被意意想不到到地改变变。它是是

27、connst因因为程序序不应该该试图去去修改它它。2). 是是的。尽尽管这并并不很常常见。一一个例子子是当一一个中服服务子程程序修该该一个指指向一个个buffferr的指针针时。3). 这这段代码码的有个个恶作剧剧。这段段代码的的目的是是用来返返指针*ptrr指向值值的平方方,但是是,由于于*pttr指向向一个vvolaatille型参参数,编编译器将将产生类类似下面面的代码码:int ssquaare(vollatiile intt *pptr)int aa,b;a = *ptrr;b = *ptrr;returrn aa * b;由于*pttr的值值可能被被意想不不到地该该变,因因此a和和

28、b可能能是不同同的。结结果,这这段代码码可能返返不是你你所期望望的平方方值!正正确的代代码如下下:long squuaree(voolattilee innt *ptrr)int aa;a = *ptrr;returrn aa * a;24、三种种基本的的数据模模型答:按照数数据结构构类型的的不同,将将数据模模型划分分为层次次模型、网网状模型型和关系系模型。25、结构构与联合合有和区区别?答:(1). 结结构和联联合都是是由多个个不同的的数据类类型成员员组成, 但在在任何同同一时刻刻, 联联合中只只存放了了一个被被选中的的成员(所所有成员员共用一一块地址址空间), 而结结构的所所有成员员都存在

29、在(不同同成员的的存放地地址不同同)。(22). 对于联联合的不不同成员员赋值, 将会会对其它它成员重重写,原来成成员的值值就不存存在了, 而对对于结构构的不同同成员赋赋值是互互不影响响的26、描述述内存分分配方式式以及它它们的区区别?答:1) 从静态态存储区区域分配配。内存存在程序序编译的的时候就就已经分分配好,这这块内存存在程序序的整个个运行期期间都存存在。例例如全局局变量,sstattic 变量。2) 在栈上上创建。在在执行函函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。3) 从堆上分配,亦称动态内存分配。程序

30、在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多27、请说说出coonstt与#ddefiine 相比,有有何优点点?答:Connst作作用:定定义常量量、修饰饰函数参参数、修修饰函数数返回值值三个作作用。被被Connst修修饰的东东西都受受到强制制保护,可可以预防防意外的的变动,能能提高程程序的健健壮性。1) coonstt 常量量有数据据类型,而而宏常量量没有数数据类型型。编译译器可以以对前者者进行类类型安全全检查。而而对后者者只进行行字符替替换,没没有类型型安全检检

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

32、eoff 可以以计算出出数组的的容量(字字节数)。sizeof(p),p 为指针得到的是一个 指针变量的字节数,而不是p 所指的内存容量。C+/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。 char a = hello world; char *p = a; cout sizeof(a) endl; / 12 字节 cout sizeof(p) endl; / 4 字节 计算数组和指针的内存容量 void Func(char a100) cout sizeof(a) endl; / 4 字节而不是100 字节

33、 29、分别别写出BBOOLL,innt,ffloaat,指指针类型型的变量量a 与与“零”的的比较语语句。答:BOOOL : iff ( !a ) oor iif(aa)innt : iif ( a = 0)ffloaat :connst EXPPRESSSIOON EEXP = 00.00000001 iif ( a -EXXP)ppoinnterr : if ( aa != NUULL) orr iff(a = NULLL) 30、如何何判断一一段程序序是由CC 编译译程序还还是由CC+编编译程序序编译的的?答:#iffdeff _cplluspplusscouutc+;#ellsecc

34、outtc;#enndiff31、论述述含参数数的宏与与函数的的优缺点点答: 带带参宏 函数处理时间 编译时时 程程序运行行时参数类型 没没有参数数类型问问题 定义义实参、形形参类型型处理过程 不不分配内内存 分配配内存程序长度 变变长 不变变运行速度 不不占运行行时间 调用和和返回占占用时间间32、用两两个栈实实现一个个队列的的功能?要求给给出算法法和思路路!答 、设22个栈为为A,BB, 一一开始均均为空.入队:将新元素ppushh入栈AA;出队:(1)判断断栈B是是否为空空;(2)如果果不为空空,则将将栈A中中所有元元素依次次popp出并ppushh到栈BB;(3)将栈栈B的栈栈顶元素素

35、popp出;这样实现的的队列入入队和出出队的平平摊复杂杂度都还还是O(1), 比上上面的几几种方法法要好33、嵌入入式系统统中经常常要用到到无限循循环,你你怎么样样用C编编写死循循环呢?答:这个问问题用几几个解决决方案。我我首选的的方案是是:whilee(1)一些程序员员更喜欢欢如下方方案:for(;)这个实现方方式让我我为难,因因为这个个语法没没有确切切表达到到底怎么么回事。如如果一个个应试者者给出这这个作为为方案,我我将用这这个作为为一个机机会去探探究他们们这样做做的基本原理。如如果他们们的基本本答案是是:“我我被教着着这样做做,但从从没有想想到过为为什么。”这这会给我我留下一一个坏印印象

36、。第三个方案案是用 gottoLoop:.goto Looop;应试者如给给出上面面的方案案,这说说明或者者他是一一个汇编编语言程程序员(这这也许是是好事)或或者他是是一个想想进入新新领域的的BASSIC/FORRTRAAN程序序员。34、位操操作(BBit mannipuulattionn) 答: 嵌入入式系统统总是要要用户对对变量或或寄存器器进行位位操作。给给定一个个整型变变量a,写写两段代代码,第第一个设设置a的的bitt 3,第第二个清清除a 的biit 33。在以以上两个个操作中中,要保保持其它它位不变变。对这这个问题题有三种种基本的的反应11)不知知道如何何下手。该该被面者者从没做

37、做过任何何嵌入式式系统的的工作。2) 用bit fields。Bit fields是被扔到C语言死角的东西,它保证你的代码在不同编译器之间是不可移植的,同时也保证了的你的代码是不可重用的。我最近不幸看到 Infineon为其较复杂的通信芯片写的驱动程序,它用到了bit fields因此完全对我无用,因为我的编译器用其它的方式来实现bit fields的。从道德讲:永远不要让一个非嵌入式的家伙粘实际硬件的边。3) 用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法,是应该被用到的方法。最佳的解决方案如下:#define BIT3 (0 x1 3)static int

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

39、。写代代码去完完成这一一任务。这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下: int *ptr; ptr = (int *)0 x67a9; *ptr = 0 xaa66;A more obscure approach is: 一个较晦涩的方法是: *(int * const)(0 x67a9) = 0 xaa55;即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。36、中断断(Innterrruppts)答: 中断断是嵌入入式系统统中重要要的组成成部分,这这导致了了

40、很多编编译开发发商提供供一种扩扩展让让标准CC支持中中断。具具代表事事实是,产产生了一一个新的的关键字字 _intterrruptt。下面面的代码码就使用用了_intterrruptt关键字字去定义义了一个个中断服服务子程程序(IISR),请评评论一下下这段代代码的。_interrupt double compute_area (double radius) double area = PI * radius * radius; printf(nArea = %f, area); return area;这个函数有太多的错误了,以至让人不知从何说起了:1)ISR 不能返回一个值。如果你不懂这个

41、,那么你不会被雇用的。2) ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。3) 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。4) 与第三点一脉相承,printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。37、动态态内存分分配(DDynaamicc meemorry aalloocattionn) 答:尽管不不像非嵌嵌入式

42、计计算机那那么常见见,嵌入入式系统统还是有有从堆(hheapp)中动动态分配配内存的的过程的的。那么么嵌入式式系统中中,动态态分配内内存可能能发生的的问题是是什么?这里,我我期望应应试者能能提到内内存碎片片,碎片片收集的的问题,变变量的持持行时间间等等。这这个主题题已经在在ESPP杂志中中被广泛泛地讨论论过了(主主要是 P.JJ. PPlauugerr, 他他的解释释远远超超过我这这里能提提到的任任何解释释),所所有回过过头看一一下这些些杂志吧吧!让应应试者进进入一种种虚假的的安全感感觉后,我我拿出这这么一个个小节目目:下面面的代码码片段的的输出是是什么,为为什么?chaar *ptrr;if

43、f (ptrr = (chhar *)mmallloc(0) = NUULL) pputss(GGot a nnulll poointter);eelsee puuts(Goot aa vaalidd poointter);这这是一个个有趣的的问题。最最近在我我的一个个同事不不经意把把0值传传给了函函数maallooc,得得到了一一个合法法的指针针之后,我我才想到到这个问问题。这这就是上上面的代代码,该该代码的的输出是是Goot aa vaalidd poointter。我用用这个来来开始讨讨论这样样的一问问题,看看看被面面试者是是否想到到库例程程这样做做是正确确。得到到正确的的答案固固然重要

44、要,但解解决问题题的方法法和你做做决定的的基本原原理更重重要些。38、Tyypeddef 答:Typpedeef 在在C语言言中频繁繁用以声声明一个个已经存存在的数数据类型型的同义义字。也也可以用用预处理理器做类类似的事事。例如如,思考考一下下下面的例例子:#deffinee dPPS sstruuct s *typpedeef sstruuct s * tPPS; 以以上两种种情况的的意图都都是要定定义dPPS 和和 tPPS 作作为一个个指向结结构s指指针。哪哪种方法法更好呢呢?(如如果有的的话)为为什么? 这是一一个非常常微妙的的问题,任任何人答答对这个个问题(正正当的原原因)是是应当被

45、被恭喜的的。答案案是:ttypeedeff更好。思思考下面面的例子子:dPPS pp1,pp2;ttPS p3,p4;第一个个扩展为为strructt s * pp1, p2; 上面面的代码码定义pp1为一一个指向向结构的的指,pp2为一一个实际际的结构构,这也也许不是是你想要要的。第第二个例例子正确确地定义义了p33 和pp4 两两个指针针。39、用变变量a给给出下面面的定义义答:a) 一个整整型数(AAn iinteegerr)b) 一个个指向整整型数的的指针(AA poointter to an inttegeer)c) 一个个指向指指针的的的指针,它它指向的的指针是是指向一一个整型型数

46、(AA poointter to a ppoinnterr too ann inntegger)d) 一个个有100个整型型数的数数组(AAn aarraay oof 110 iinteegerrs)e) 一个个有100个指针针的数组组,该指指针是指指向一个个整型数数的(AAn aarraay oof 110 ppoinnterrs tto iinteegerrs)f) 一个个指向有有10个个整型数数数组的的指针(AA poointter to an arrray of 10 inttegeers)g) 一个个指向函函数的指指针,该该函数有有一个整整型参数数并返回回一个整整型数(AA pooi

47、ntter 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 inttegeerargummentt annd rretuurn an inttegeer )答案是:a) innt aa; / AAn iinteegerrb)

48、 innt *a; / A ppoinnterr too ann innteggerc) innt *a; / A poiinteer tto aa poointter to an inttegeerd) innt aa100; / An arrray of 10 inttegeerse) innt *a110; / Ann arrrayy off 100 poointterss too innteggerssf) innt (*a)100; / A ppoinnterr too ann arrrayy off 100 innteggerssg) innt (*a)(innt); / A po

49、iinteer tto aa fuuncttionn a thaat ttakees aan iinteegerr arrgummentt annd rretuurnss ann innteggerh) innt (*a10)(iint); / AAn aarraay oof 110 ppoinnterrs tto ffuncctioons thaat ttakee ann inntegger arggumeent andd reeturrn aan iinteegerr40、解释释局部变变量、全全局变量量和静态态变量的的含义。答:41、写一一个“标标准”宏宏答:交换两两个参数数值的宏宏定义为

50、为:. #deefinne SSWAPP(a,b) (a)=(a)+(bb);(b)=(a)-(b);(a)=(a)-(b);输入两个参参数,输输出较小小的一个个:#ddefiine MINN(A,B) (AA) nexxt,并并随后删删除原nnextt指向的的节点。第二部分:程序代代码评价价或者找找错1、下面的的代码输输出是什什么,为为什么?voiid ffoo(voiid) unnsiggnedd innt aa = 6; intt b = -20; (aa+b 66) ? puuts( 6) : putts(6。原因因是当表表达式中中存在有有符号类类型和无无符号类类型时所所有的操操作数都

51、都自动转转换为无无符号类类型。因因此-220变成成了一个个非常大大的正整整数,所所以该表表达式计计算出的的结果大大于6。这这一点对对于应当当频繁用用到无符符号数据据类型的的嵌入式式系统来来说是丰丰常重要要的。如如果你答答错了这这个问题题,你也也就到了了得不到到这份工工作的边边缘。22、评价价下面的的代码片片断:uunsiigneed iint zerro = 0;unssignned intt coompzzeroo = 0 xFFFFFF; /*1s ccompplemmentt off zeero */对对于一个个intt型不是是16位位的处理理器为说说,上面面的代码码是不正正确的。应应编

52、写如如下:uunsiigneed iint commpzeero = 0;这这一问题题真正能能揭露出出应试者者是否懂懂得处理理器字长长的重要要性。在在我的经经验里,好好的嵌入入式程序序员非常常准确地地明白硬硬件的细细节和它它的局限限,然而而PC机机程序往往往把硬硬件作为为一个无无法避免免的烦恼恼。3、 C语语言同意意一些令令人震惊惊的结构构,下面面的结构构是合法法的吗,如如果是它它做些什什么?iint a = 5, b = 77, cc;c = aa+b;这这个问题题将做为为这个测测验的一一个愉快快的结尾尾。不管管你相不不相信,上上面的例例子是完完全合乎乎语法的的。问题题是编译译器如何何处理它

53、它?水平平不高的的编译作作者实际际上会争争论这个个问题,根根据最处处理原则则,编译译器应当当能处理理尽可能能所有合合法的用用法。因因此,上上面的代代码被处处理成:c = a+ + b;因此, 这段段代码持持行后aa = 6, b = 7, c = 112。如如果你知知道答案案,或猜猜出正确确答案,做做得好。如如果你不不知道答答案,我我也不把把这个当当作问题题。我发发现这个个问题的的最大好好处是这这是一个个关于代代码编写写风格,代代码的可可读性,代代码的可可修改性性的好的的话题。4、设有以以下说明明和定义义:typeddef uniion loong i; intt k5; chhar c; D

54、AATE;strucct ddataa intt caat; DATTE ccow; dooublle ddog; ttoo;DATE maxx;则语句 pprinntf(%dd,ssizeeof(strructt daate)+siizeoof(mmax);的的执行结结果是? 答 、结果果是:552。DDATEE是一个个uniion, 变量量公用空空间. 里面最最大的变变量类型型是innt55, 占用220个字字节. 所以它它的大小小是200data是是一个sstruuct, 每个个变量分分开占用用空间. 依次次为innt4 + DDATEE20 + ddoubble88 = 32.所以结果

55、是是 200 + 32 = 552.当然.在某些些16位位编辑器器下, intt可能是是2字节节,那么么结果是是 innt2 + DDATEE10 + ddoubble88 = 205、请写出出下列代代码的输输出内容容#inclludeemain()int aa,b,c,dd;a=10;b=a+;c=+aa;d=10*a+;printtf(b,cc,d:%d,%d,%d,bb,c,dd);returrn 00; 答:10,112,11206、写出下下列代码码的输出出内容#inclludeeint iinc(intt a)returrn(+a);int mmultti(iint*a,iint*b

56、,iint*c)returrn(*c=*a*b);typeddef intt(FUUNC11)(iint in);typeddef intt(FUUNC22) (intt*,iint*,innt*);void shoow(FFUNCC2 ffun,intt arrg1, innt*aarg22)INCp=&innc;int ttempp =pp(arrg1);fun(&temmp,&argg1, argg2);printtf(%dn,*arrg2);main()int aa;show(mullti,10,&a);returrn 00;答:11007、请找出出下面代代码中的的所以错错误说明:以下

57、下代码是是把一个个字符串串倒序,如如“abbcd”倒倒序后变变为“ddcbaa”1、#inncluudestrringg.h2、maiin()3、4、 chhar*srcc=hhelllo,wworlld;5、 chhar* deest=NULLL;6、 innt llen=strrlenn(srrc);7、 deest=(chhar*)maallooc(llen);8、 chhar* d=desst;9、 chhar* s=srccleen;10、 wwhille(llen-!=0) 11、 dd+=s-;12、 pprinntf(%ss,ddestt);13、 rretuurn 0;14、

58、答:方法1:int mmainn()char* srrc = hhelllo,wworlld;int llen = sstrllen(srcc);char* deest = (chaar*)malllocc(leen+11);/要为为0分分配一个个空间char* d = ddestt;char* s = &srccleen-11;/指向向最后一一个字符符whilee( llen- != 00 )*d+=*s-;*d = 0;/尾部部要加0printtf(%sn,desst);free(desst);/ 使用完完,应当当释放空空间,以以免造成成内存汇汇泄露returrn 00;方法2:#incl

59、ludee #inclludee main()char strr=heelloo,woorldd;int llen=strrlenn(sttr);char t;for(iint i=00; iileen/22; ii+)t=strri; strii=sstrlenn-i-1; sttrllen-i-11=tt;printtf(%s,sttr);returrn 00;8、请问下下面程序序有什么么错误? innt aa600225010000,i,j,kk; foor(kk=0;k=10000;kk+) ffor(j=00;j2500;j+) forr(i=0;ii600;i+) aijk=0;答

60、案:把循循环语句句内外换换一下9、请问下下面程序序会出现现什么情情况?. #deefinne MMax_CB 5000 vvoidd LmmiQuueryyCSmmd(SStruuct MSggCB * ppmsgg) unssignned chaar uucCmmdNuum; . forr(uccCmddNumm=0;ucCCmdNNumMaxx_CBB;uccCmddNumm+) .; 答案:死循循环10、以下下3个有有什么区区别chhar * cconsst pp; /常量量指针,pp的值不不可以修修改char connst * pp;/指向常常量的指指针,指指向的常常量值不不可以改改c

温馨提示

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

评论

0/150

提交评论