《c,c++面试题.pdf》由会员分享,可在线阅读,更多相关《c,c++面试题.pdf(46页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、常见的C语言笔试题1 .C+的类和C 里面的s t r u c t 有什么区别?s t r u c t 成员默认访问权限为p u b l i c,而 c l a s s 成员默认访问权限为p r i v a t e2 .析构函数和虚函数的用法和作用析构函数是在对象生存期结束时自动调用的函数,用来释放在构造函数分配的内存。虚函数是指被关键字v i r t u a l 说明的函数,作用是使用C+语言的多态特性3 .全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?1)全局变量的作用用这个程序块,而局部变量作用于当前函数2)前者在内存中分配在全局数据区,后者分配在栈区3)生命
2、周期不同:全局变量随主程序创建和创建,随主程序销毁而销毁,局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在4)使用方式不同:通过声明后全局变量程序的各个部分都可以用到,局部变量只能在局部使用4 .有 N 个大小不等的自然数(1-N),请将它们由小到大排序.要求程序算法:时间复杂度为0(n),空间复杂度为0(1)。v o i d s o r t(i n t e ,i n t n)i n t i;i n t t;f o r (i=l;it =e e i ;e e i =e i ;e i =t;5 .堆与栈的去区别A.申请方式不同S t a c k 由系统自动分配,而 h e a p
3、需要程序员自己申请,并指明大小。B.申请后系统的响应不同S t a c k:只要栈的剩余空间大于申请空间,系统就为程序提供内存,否则将抛出栈溢出异常H e a p:当系统收到程序申请时,先遍历操作系统中记录空闲内存地址的链表,寻找第一个大于所申请空间的堆结点,然后将该结点从空间结点链表中删除,并将该结点的空间分配给程序。另外,大多数系统还会在这块内存空间中的首地址处记录本次分配的大小,以便于d e l e t e 语句正确释放空间。而且,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入空闲链表。C.申请大小限制的不同S t a c k:在w i n d o w
4、s下,栈的大小是2 M (也可能是I M它是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示o v e r f l o w。因此,能从栈获得的空间较小。H e a p:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。D.申请效率的比较:栈由系统自动分配,速度较快。但程序员是无法控制的。堆是由n e w分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。另外,在W I N D O W
5、S下,最好的方式是用V i r t u a l A l l o c分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。E.堆和栈中的存储内容栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编 译 器 中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体
6、内容有程序员安排。6 .含参数的宏与函数的优缺点宏:优点:在预处理阶段完成,不占用编译时间,同时,省去了函数调用的开销,运行效率高缺点:不进行类型检查,多次宏替换会导致代码体积变大,而且由于宏本质上是字符串替换,故可能会由于一些参数的副作用导致得出错误的结果。函数:优点:没有带参数宏可能导致的副作用,进行类型检查,计算的正确性更有保证。缺点:函数调用需要参数、返回地址等的入栈、出栈开销,效率没有带参数宏高P S:宏与内联函数的区别内联函数和宏都是在程序出现的地方展开,内联函数不是通过函数调用实现的,是在调用该函数的程序处将它展开(在编译期间完成的):宏同样是;不同的是:内联函数可以在编译期间完
7、成诸如类型检测,语句是否正确等编译功能;宏就不具有这样的功能,而且宏展开的时间和内联函数也是不同的(在运行期间展开)7 .W ind ow s程序的入口是哪里?写出W ind ow s消息机制的流程W ind ow s程序的入口是W inM a in()函数。W ind ow s应用程序消息处理机制:A.操作系统接收应用程序的窗口消息,将消息投递到该应用程序的消息队列中B.应用程序在消息循环中调用G e t M e s s a ge函数从消息队列中取出一条一条的消息,取出消息后,应用程序可以对消息进行一些预处理。C.应用程序调用D is p a t c hM e s s a ge,将消息回传给
8、操作系统。D.系统利用W N D C L A S S结构体的I p fnW nd P r oc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理。8.如何定义和实现一个类的成员函数为回调函数A.什么是回调函数?简而言之,回调函数就是被调用者回头调用调用者的函数。使用回调函数实际上就是在调用某个函数(通常是A P I函 数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个被调用函数。而该被调用函数在需要的时候,利用传递的地址调用回调函数。回调函数,就是由你自己写的,你需要调用另外一个函数,而这个函数的其中一个参数,就是你的这个回调函数名。这样,系统在必要的时候,就会调用你
9、写的回调函数,这样你就可以在回调函数里完成你要做的事。B.如何定义和实现一个类的成员函数为回调函数要定义和实现一个类的成员函数为回调函数需要做三件事:a.声明;b.定义;c.设置触发条件,就是在你的函数中把你的回调函数名作为一个参数,以便系统调用如:一、声明回调函数类型t y p e d e f v oid (*F u nP t r)(v oid);二、定义回调函数c la s s A(p u b lic:A O;s t a t ic v oid c a llB a c kF u n(v oid)/回调函数,必须声明为 s t a t ic(c ou t u n s i g n e d c h
10、 a r *p l;u n s i g n e d l on g *p 2;p l=(u n s i g n e d c h a r *)0X 8 01000;p 2=(u n s i g n e d l on g *)0X 8 10000;请问 p l+5=0X 8 01005;p 2+5=0X 8 01014;19.多态的作用?主要是两个:L隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2.接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。2 0.A d o与A d o.n e t的相同与不同?除了“能够让应用程序处理存储于DB M S
11、中的数据“这一基本相似点外,两者没有太多共同之处。但是A d o使用O LE D B 接口并基于微软的C O M 技术,而A DO.N ET拥有自己的A DO.N ET 接口并且基于微软的.N ET 体系架构。众所周知.N ET 体系不同于C O M 体 系,A DO.N ET 接口也就完全不同于A DO 和 O LE D B 接口,这也就是说A DO.N ET 和 A DO 是两种数据访问方式。A DO.n e t提供对X M L的支持。2 1.N e w d e le te 与 m a lloc f re e 的联系与区别?都是在堆(h e a p)上进行动态的内存操作。用m a lloc
12、 函数需要指定内存分配的字节数并且不能初始化对象,n e w 会自动调用对象的构造函数。d e le te 会调用对象的d e struc tor,而 f re e 不会调用对象的d e struc tor.2 2.#d e f i n e DO U B LE(x)x+x ,i =5*D0 U B LE(5);i 是多少?答案:i为 3 0。IT公司面试手册首 页 发 布 招 聘 猎头职位”各大公司面试题内 关于我们 J a va.侬 J S P S e rvle t S truts S pri n g H i b e rn a te EJ B S O A A J A X W e b 开发.软
13、件工程.项目管理 JJ1ET ASP.NET C#C+c语言.ASP.PHP Ruby Python Delphi Linux UNIX.数据库 Oracle SQL Server MySQL Mobile 开发嵌 入式开发 网络安全网络技术.综合技术 HR面试.英语面试 外企面试.软件测试.QTP LoadRunner 网友面经 应届生 面试指导 IQ智力 Flex经典C+面试题目与参考答案C+倒囹一、请填写BOOL,float,指 针 变 量 与“零值”比 较 的i f语句。(10分)请 写 出B O O L f la g与“零值”比 较 的i f语句。(3分)标准答案:i f (f la
14、 g )i f (!f la g )如下写法均属不良风格,不得分。i f (f la g =T R U E)if (f l a g=1 )if (f l a g=F A L S E)if (f l a g=0)请 写 出f l o a t x与“零值”比 较 的i f语句。(4分)标准答案示例:c o nst f l o a t E P S I N O N =0.00001;if (x =-E P S I N O N)&(x =”或“仁”此类形式。如下是错误的写法,不得分。if (x=0.0)if (x!=0.0)请 写 出c ha r *p与 零 值 比 较 的i f语句。(3分)标准答案:
15、if (p =N U L L)if (p !=N U L L)如下写法均属不良风格,不得分。=0)!=0)/!7ppp!7l/lz(zffff1iii二、以下为W ind o ws N T下 的32位C+程序,请计算siz e o f的 值(10分)请计算 vo id F unc (c ha r str 100)(siz e o f (str )=4(2 分)vo id *p =ma l l o c(100);请计算siz e o f (p )=4(2 分)三、简 答 题(25分)1、头文件中的if nd e f/d e f ine/e nd if 干什么用?(5分)答:防止该头文件被重复引用
16、。2、inc l ud e 和 S inc l ud e f il e na me,h”有什么区别?(5 分)答:对于#inc l ud e ,编译器从标准库路径开始搜索f il e na me.h对于#inc l ud e “f il e na me 4”,编译器从用户的工作路径开始搜索f il e na me.h3、c o nst有什么用途?(请至少说明两种)(5分)答:(1)可以定义c o nst常量(2)c o nst可以修饰函数的参数、返回值,甚至函数的定义体。被 c o nst修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。4、在C+程序中调用被C 编译器编译后的
17、函数,为什么要加e xte r n C”?(5分)答:C+语言支持函数重载,C 语言不支持函数重载。函数被C+编译后在库中的名字与C 语言的不同。假设某个函数的原型为:vo id f o o(int x,int y);该函数被C编译器编译后在库中的名字为_ f。,而C+编译器则会产生像_ f o o _ int_ int之类的名字。C+短供/C连接交换指定符号e xte r n“C”来解决名字匹配问题。5、请简述以下两个f o r 循环的优缺点(5分)f o r (i=0;iif (c o nd itio n)D o S o me thing();e l seD o O the r thing
18、();if (c o nd itio n)(f o r (i=0;iD o S o me thing();)e l sef o r (i=0;iD o O the r thing();)优点:程序简洁缺点:多执行了 NT次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。优点:循环的效率高缺点:程序不简洁四、有关内存的思考题(每小题5 分,共 2 0 分)v o i d Ge t Me m o r y(c h a r *p)(p =(c h a r *)m a l l o c(1 0 0);)v o i d Te s t(v o i d)(c h a r *
19、s t r =NULL;Ge t Me m o r y(s t r);s t r c p y(s t r,h e l l o w o r l d”);p r i n t f(s t r);)请问运行Te s t 函数会有什么样的结果?答:程序崩溃。因为Ge t Me m o r y 并不能传递动态内存,Te s t 函数中的s t r 一直都 是 NULL。s t r c p y(s t r,uh e l l o w o r l d );将使程序崩溃。c h a r *Ge t Me m o r y(v o i d)c h a r p =h e l l o w o r l d ;r e t u
20、 r n p;)v o i d Te s t(v o i d)(c h a r *s t r =NULL;s t r =Ge t Me m o r y ();p r i n t f(s t r);)请问运行Te s t 函数会有什么样的结果?答:可能是乱码。因为Ge t Me m o r y 返回的是指向“栈内存”的指针,该指针的地址不是NULL,但其原现的内容已经被清除,新内容不可知。v o i d Ge t Me m o r y 2(c h a r *p,i n t n u m)(*p =(c h a r *)m a l l o c(n u m);v o i d Te s t(v o i
21、d)(c h a r *s t r =NULL;Ge t Me m o r y(&s t r,1 0 0);s t r c p y (s t r,h e l l o”);p r i n t f (s t r);请问运行Te s t 函数会有什么样的结果?答:(1)能够输出h e l l o(2)内存泄漏v o i d Te s t(v o i d)(c h a r *s t r =(c h a r *)m a l l o c(1 0 0);s t r c p y(s t r,h e l l o );f r e e(s t r);i f (s t r !=NULL)s t r c p y (s
22、t r,w o r l d );p r i n t f (s t r);)请问运行Te s t 函数会有什么样的结果?答:篡改动态内存区的内容,后果难以预料,非常危险。因为f r e e (s t r);之后,s t r 成为野指针,i f(s t r !=NULL)语句不起作用。五、编写s t r c p y 函 数(1 0 分)已知s t r c p y 函数的原型是c h a r *s t r c p y(c h a r *s t r De s t,c o n s t c h a r *s t r Sr c);其中s t r De s t 是目的字符串,s t r Sr c 是源字符串。
23、(1)不调用C+/C的字符串库函数,请编写函数s t r c p yc h a r *s t r c p y(c h a r *s t r De s t,c o n s t c h a r *s t r Sr c);a s s e r t(s t r De s t!=NULL)&(s t r Sr c !=NULL);/2 分c h a r a d d r e s s =s t r De s t;/2 分w h i l e(*s t r De s t+=*s t r Sr c+)!=0 )2 分NULL;r e t u r n a d d r e s s ;2 分(2)s t r c p y
24、能把s t r Sr c 的内容复制到s t r De s t,为什么还要c h a r *类型的返回值?答:为了实现链式表达式。2 分例如 i n t l e n g t h =s t r l e n(s t r c p y(s t r De s t,“h e l l o w o r l d );六、编写类St r i n g 的构造函数、析构函数和赋值函数(2 5 分)已知类St r i n g 的原型为:c l a s s St r i n gpublic:String(const char*str=NULL);/普通构造函数String(const String Mother);/拷贝
25、构造函数 String(void);/析构函数String&operate=(const String feother);/赋值函数private:char*m_data;/用于保存字符串);请编写String的上述4 个函数。标准答案:/String的析构函数String:String(void)3 分delete m_data;/由于m_data是内部数据类型,也可以写成delete m_data;)/String的普通构造函数String:String(const char*str)6 分if(str=NULL)(m_data=new char 1;/若能加NULL判断则更好*m_dat
26、a=0;)else(int length=strlen(str);m_data=new charlength+1;/若能加 NULL 判断则更好strcpy(m_data,str);)/拷贝构造函数String:String(const String&other)/3 分(int length=strlen(other.m_data);m_data=new charlength+1;/若能加 NULL 判断则更好strcpy(m_data,other.m_data);)/赋值函数String&String:operate=(const String feother)/13 分 检 查 自 赋
27、值 4 分i f(t h i s =&o t h e r)r e t u r n *t h i s;/(2)释放原有的内存资源 3 分d e l e t e 口 m _d a t a;/(3)分配新的内存资源,并复制内容 3 分i n t l e n g t h =s t r l e n(o t h e r.m _d a t a);m _d a t a =n e w c h a r l e n g t h+1;/若能加 NULL 判断则更好s t r c p y(m _d a t a,o t h e r.m _d a t a);/(4)返回本对象的引用 3 分r e t u r n *t h
28、i s;许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的s t r c p y 函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一个s t r c p y 函数吗?我们都觉得自己能,可是我们写出的s t r c p y 很可能只能拿到1 0 分中的2 分。读者可从本文看到s t r c p y 函数从2 分到 1 0 分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。2.找错题试题1 :v o i
29、d t e s t l ()c h a r s t r i n g 1 0 ;c h a r*s t r l =0 1 2 3456 7 8 9 ;s t r c p y(s t r i n g,s t r l );试题2:v o i d t e s t 2 0c h a r s t r i n g 1 0 ,s t r l 1 0 ;i n t i;f o r(i=0;i 1 0:i+)(s t r l i =a ;s t r c p y (s t r i n g,s t r l );)试题3:v o i d t e s t 3(c h a r*s t r l)(c h a r s t r
30、i n g 1 0 ;i f(s t r l e n(s t r l )=1 0 )(s t r c p y(s t r i n g,s t r l );)解答:试题1字符串s t r l需要1 1个字节才能存放下(包括末尾的 0 ),而s t r i n g只有1 0个字节的空间,s t r c p y会导致数组越界;对试题2,如果面试者指出字符数组s t门不能在数组内结束可以给3分;如果面试者指出s t r c p y (s t r i n g,s t r l)调用使得从s t r l内存起复制到s t r i n g内存起所复制的字节数具有不确定性可以给7 分,在此基础上指出库函数s t
31、 r c p y 工作方式的给1 0 分;对试题 3,i f (s t r l e n (s t r l)=1 0)应改为 i f (s t r l e n(s t r l)1 0),因为 s t r l e n的结果未统计 0 所占用的1 个字节。剖析:考查对基本功的掌握:(1)字符串以 0 结尾;(2 )对数组越界把握的敏感度;(3)库函数s t r c p y 的工作方式,如果编写一个标准s t r c p y 函数的总分值为1 0,下面给出几个不同得分的答案:2 分v o i d s t r c p y (c h a r *s t r D e s t,c h a r *s t r S
32、r c )w h i l e(*s t r D e s t+=*s t r S r c+)!=0 );)4 分v o i d s t r c p y(c h a r *s t r D e s t,c o n s t c h a r *s t r S r c )将源字符串加c o n s t,表明其为输入参数,加 2 分w h i l e(*s t r D e s t+=*s t r S r c+)!=0 );)7分v o i d s t r c p y(c h a r *s t r D e s t,c o n s t c h a r *s t r S r c)/对源地址和目的地址加非0断言,加
33、 3 分assert(strDest!=NULL)&(strSrc!=NULL);while(*strDest+=*strSrc+)!=0 );)10分为了实现链式操作,将目的地址返回,加3分!char*strcpy(char*strDest,const char*strSrc)(assert(strDest!=NULL)&(strSrc!=NULL);char*address=strDest;while(*strDest+=*strSrc+)!=0 );return address;)从2分到10分的儿个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实
34、的基本功才能写一个完美的strcpy啊!(4)对strlen的掌握,它没有包括字符串末尾的 0。读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:int strlen(const char*str)输入参数 const(assert(strt!=NULL);/断言字符串地址非0int len;while(*str+)!=0 )len+;return len;试题4:void G etM emory(char*p)(p=(char*)malloc(1 0 0 );)void T est(void)Ichar*str=N U L L;G etM emo
35、ry(str);strcpy(str,hello world );printf(str);)试题5:char*G etM emory(void)(char p =hello world”;return p;void T est(void)char*str=N U L L;str=G etM emoryO ;printf(str);)试 题6:void G etM emory(char*p,int num)(*p=(char*)malloc(num);)void T est(void)Ichar*str=N U L L;G etM emory(&str,1 0 0 );strcpy(str,he
36、llo);printf(str);)试 题7 :void T est(void)(char*str=(char*)malloc(1 0 0 );strcpy(str,hello);f ree(str);省略的其它语句解答:试题4 传入中G etM emory(char*p)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完char*str=N U L L;G etM emory(str);后的str仍然为N U L L;试题5中char p =hello world”;return p;的P 数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常
37、犯的错误,其根源在于不理解变量的生存期。试题6的G etM emory避免了试题4的问题,传入G etM emory的参数为字符串指针的指针,但是在G etM emcay中执行申请内存及赋值语句1 .以下三条输出语句分别输出什么?C 易char strl=abc”;char str2 =abc”;const char str3 =abc;const char str4 =abc”;const char*str5 =abc”;const char*str6 =abc”;cout boolalpha (strl=str2 )endl;/输出什么?cout boolalpha (str3=str4
38、)endl;/输出什么?cout boolalpha (str5=str6 )endl;/输出什么?2 .非C+内建型别A和 B,在哪儿种情况下B能隐式转化为A?C+中等答:a.class B :public A .b.class B operator A();c.class A A(const B&);B 公有继承自A,可以是间接继承的/B实现了隐式转化为A的转化/A实现了 non-explicit的参数为B (可以有其他带默认值的参数)构造函数d.A&operator=(const A&);/赋值操作,虽不是正宗的隐式类型转换,但也可以勉强算一个3 .以下代码中的两个sizeo f 用法有
39、问题吗?C 易v o i d U p p er c as e(c h ar s t r )/将 s t r 中的小写字母转换成大写字母f o r (s i z e_t i=0;ii f (a =s t r i&s t r i =,z)s t r i 一=(a-A);c h ar s t r =aB c D e;c o u t s t r 字符长度为:s i z eo f (s t r)/s i z eo f (s t r 0 )en d l;U p p er C as e(s t r );c o u t s t r =0&n =9 )r et u r n v a ls n ;els e c o
40、 u t,/s u b s c r ip t er r o r”;r et u r n er r o r;)(5)在另外的一些操作符中,却千万不能返回引用:+-*/四则运算符。它们不能返回引用,E ffec t iv e C+l的I t em2 3详细的讨论了这个问题。主要原因是这四个操作符没有s id e effec t,因此,它们必须构造一个对象作为返回值,可选的方案包括:返回-一 个对象、返 回-个局部变量的引用,返回一个n ew分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,第2、3两个方案都被否决了。静态对象的引用又因为(a+b)=(c+d)会永远为t
41、 r u e而导致错误。所以可选的只剩下返回一个对象了。6.引用与多态的关系?引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。例4C la ss A;C la ss B:C la ss A.;B b;A&r e f =b;7.引用与指针的区别是什么?指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。此外,就是上面提到的对函数传r e f和p o inte r的区别。8.什 么 时 候 需 要“引用”?流操作符 和 、赋值操作符=的返回值、拷贝构
42、造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用9.结构与联合有和区别?1.结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员(所有成员共用一块地址空间),而结构的所有成员都存在(不同成员的存放地址不同)。2.对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构的不同成员赋值是互不影响的。10.下面关于“联合”的题目的输出?a)ttinc lu d eu nio n(int i;c h a r x 2;a;v o id ma in()(a.x 0 =10;a.x l =1;p r intf (%d ,a.i);)答案:
43、266(低位低地址,高位高地址,内存占用情况是O x O lO A)b)ma inO(u nio n int i;str u c t c h a r f ir st;c h a r se c o nd;h a lf;nu mb e r;nu mb e r.i=0X 4241;p r intf (%c%c n”,nu mb e r.h a lf,f ir st,mu mb e r.h a lf,se c o nd);nu mb e r,h a lf,f ir st=a,;nu mb e r.h a lf,se c o nd=b ;p r intf (%x n,nu mb e r,i);g e t
44、c h O ;)答案:AB(0X 41对应 A,是低位;0 x 42对应 B,是高位)6261(nu mb e r,i 和 nu mb e r,h a lf 共用一块地址空间)11.已知 str c p y 的函数原型:c h a r *str c p y (c h a r *str D e st,c o nst c h a r *str S r c)其中str D e st是目的字符串,str S r c 是源字符串。不调用C+/C 的字符串库函数,请编写函数str c p y o答案:c h a r *str c p y (c h a r *str D e st,c o nst c h a
45、 r *str S r c)(if (str D e st=N U L L|str S r c =N U L L)r e tu r n N U L L ;if (str D e st=str S r c)r e tu r n str D e st;c h a r *te mp p tr =str D e st;w h ile(*str D e st+=*str S r c+)!=0 )r e tu r n te mp p tr ;)1 2.已知S tr ing类定义如下:c la ss S tr ingp u b lic:S tr ing (c o nst c h a r *str =N U
46、L L);/通用构造函数S tr ing (c o nst S tr ing&a no th e r);/拷贝构造函数 S tr ing O;/析构函数S tr ing&o p e r a te r =(c o nst S tr ing&r h s);/赋值函数p r iv a te:c h a r *m_ d a ta;/用于保存字符串);尝试写出类的成员函数实现。答案:S tr ing:S tr ing(c o nst c h a r *str)(if (str =N U L L )str le n在参数为N U L L时会抛异常才会有这步判断(m_ d a ta =ne w c h a
47、r 1 ;m_ d a ta 0 =0;)e lsem_ d a ta =ne w c h a r str le n(str)+1;str c p y (m_ d a ta,str);)S tr ing:S tr ing(c o nst S tr ing&a no th e r)(m_ d a ta =ne w c h a r str le n(a no th e r.m_ d a ta)+1;str c p y(m_ d a ta,o th e r.m_ d a ta);)S tr ing&S tr ing:o p e r a to r =(c o nst S tr ing&r h s)(i
48、f (th is=&r h s)r e tu r n*th is;d e le te m_ d a ta;删除原来的数据,新开一块内存m_ d a ta =ne w c h a r str le n(r h s.m_ d a ta)+1;str c p y (m d a ta,r h s.m_ d a ta);r e tu r n*th isS tr ing:S tr ing ()d e le te m_ _ d a ta ;)13.h 头文件中的 i f n d e f/d e f i n e/e n d i f 的作用?答:防止该头文件被重复引用。14.#i n cl u d e 与 W
49、i n cl u d e f i l e,h”的区别?答:前者是从S t a n d a r d L i b r a r y 的路径寻找和引用f i l e.h,而后者是从当前工作路径搜寻并引用f i l e.h o15.在 C+程序中调用被C编译器编译后的函数,为什么要加e x t e r n “C”?首先,作为e x t e r n 是C/C+语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字 e x t e r n 声明。例如,如果模块B 欲引用该
50、模块A 中定义的全局变量和函数时只需包含模块A 的头文件即可。这样,模块B 中调用模块A 中的函数时,在编译阶段,模块B 虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A 编译生成的目标代码中找到此函数e x t e r n C 是连接申明(l i n k a g e d e cl a r a t i o n),被 e x t e r n C 修饰的变量和函数是按照C语言方式编译和连接的,来看看C+中对类似C的函数是怎样编译的:作为一种面向对象的语言,C+支持函数重载,而过程式语言C则不支持。函数被 C+编译后在符号库中的名字与C 语言的不同。例如,假设某个函数的原型为:v o i