C_c++语言面试宝典整理5051.docx

上传人:you****now 文档编号:68917805 上传时间:2022-12-30 格式:DOCX 页数:51 大小:166.91KB
返回 下载 相关 举报
C_c++语言面试宝典整理5051.docx_第1页
第1页 / 共51页
C_c++语言面试宝典整理5051.docx_第2页
第2页 / 共51页
点击查看更多>>
资源描述

《C_c++语言面试宝典整理5051.docx》由会员分享,可在线阅读,更多相关《C_c++语言面试宝典整理5051.docx(51页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、1.new、delete、malloc、free关系delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。malloc与free是C+/C语言的标准库函数,new/delete是C+的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C+语言需要一个能完成动态内存分配和初始化工作的

2、运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。2.delete与 delete 区别?delete只会调用一次析构函数,而delete会调用每一个成员的析构函数。在MoreEffectiveC+中有更为详细的解释:“当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operatordelete来释放内存。”delete与New配套,delete 与new 配套 MemmTesst*mmTesst1=newwMemmTesst110;MemmTesst*mmTesst2=newwMemmTesst;iint*pInnt

3、1=newwintt100; intt*pIInt22=neewinnt; delleteeppIntt1; /-1- deelettepInnt2; /-22- ddeleetemTTestt1;/-33- ddeleetemTTestt2;/-44-在-4-处处报错。这就说明:对于内建简单数据类型,delete和delete功能是相同的。对于自定义的复杂数据类型,delete和delete不能互用。delete删除一个数组,delete删除一个指针简单来说,用new分配的内存用delete删除用new分配的内存用delete删除delete会调用数组元素的析构函数。内部数据类型没有析构函数

4、,所以问题不大。如果你在用delete时没用括号,delete就会认为指向的是单个对象,否则,它就会认为指向的是一个数组。3.C CC+ JAVVA共同同点,不不同之处处?4.继承优优缺点。类继承是在编译时刻静态定义的,且可直接使用,类继承可以较方便地改变父类的实现。但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。更糟的是,父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为。如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。(待补充)5.C+有哪些些性质

5、(面面向对象象特点)?封装,继承和多态。在面向对象程序设计语言中,封装是利用可重用成分构造软件系统的特性,它不仅支持系统的可重用性,而且还有利于提高系统的可扩充性;消息传递可以实现发送一个通用的消息而调用不同的方法;封装是实现信息隐蔽的一种技术,其目的是使类的定义和实现分离。6.子类析析构时要要调用父父类的析析构函数数吗?析析构函数数调用的的次序是是先派生生类的析析构后基基类的析析构,也也就是说说在基类类的的析析构调用用的时候候,派生生类的信信息已经经全部销销毁了。定义一一个对象象时先调调用基类类的构造造函数、然然后调用用派生类类的构造造函数;析构的的时候恰恰好相反反:先调调用派生生类的析析构

6、函数数、然后后调用基基类的析析构函数数JAVVA无析析构函数数深拷贝贝和浅拷拷贝 7.多态,虚虚函数,纯纯虚函数数8.求下面面函数的的返回值值(微软软)int ffuncc(x) innt ccounntx = 00; whiile(x) coounttx +; x = xx&(xx-1); reeturrn ccounntx; 假定x = 99999。 答案:8。思路:将x转转化为22进制,看看含有的的1的个个数。9.什么是是“引用用”?申申明和使使用“引引用”要要注意哪哪些问题题?答:引用就就是某个个目标变变量的“别别名”(aliias),对引用的操操作与对对变量直直接操作作效果完完全相同

7、同。申明明一个引引用的时时候,切切记要对对其进行行初始化化。引用用声明完完毕后,相相当于目目标变量量名有两两个名称称,即该该目标原原名称和和引用名名,不能能再把该该引用名名作为其其他变量量名的别别名。声声明一个个引用,不不是新定定义了一一个变量量,它只只表示该该引用名名是目标标变量名名的一个个别名,它它本身不不是一种种数据类类型,因此引引用本身身不占存存储单元元,系统统也不给给引用分分配存储储单元。不能建立数组的引用。10.将“引引用”作作为函数数参数有有哪些特特点?(1)传递递引用给给函数与与传递指指针的效效果是一一样的。这这时,被被调函数数的形参参就成为为原来主主调函数数中的实实参变量量或

8、对象象的一个个别名来来使用,所所以在被被调函数数中对形形参变量量的操作作就是对对其相应应的目标标对象(在在主调函函数中)的的操作。(2)使用用引用传传递函数数的参数数,在内内存中并并没有产产生实参参的副本本,它是是直接对对实参操操作;而而使用一一般变量量传递函函数的参参数,当当发生函函数调用用时,需需要给形形参分配配存储单单元,形形参变量量是实参参变量的的副本;如果传传递的是是对象,还还将调用用拷贝构构造函数数。因此此,当参参数传递递的数据据较大时时,用引引用比用用一般变变量传递递参数的的效率和和所占空空间都好好。(3)使用用指针作作为函数数的参数数虽然也也能达到到与使用用引用的的效果,但但是

9、,在在被调函函数中同同样要给给形参分分配存储储单元,且且需要重重复使用用*指指针变量量名的的形式进进行运算算,这很很容易产产生错误误且程序序的阅读读性较差差;另一一方面,在在主调函函数的调调用点处处,必须须用变量量的地址址作为实实参。而而引用更更容易使使用,更更清晰。11.在什什么时候候需要使使用“常常引用”?如果既既要利用用引用提提高程序序的效率率,又要要保护传传递给函函数的数数据不在在函数中中被改变变,就应应使用常常引用。常引用用声明方方式:cconsst 类类型标识识符 &引用名名=目标标变量名名;例1intt a ;coonstt innt &ra=a;rra=11; /错误误a=11

10、; /正确确 例2strringg fooo( );vvoidd baar(sstriing & ss); 那么下面的的表达式式将是非非法的:bar(fooo( );bbar(heelloo woorldd); 原因在于ffoo( )和和heelloo woorldd串都都会产生生一个临临时对象象,而在在C+中,这这些临时时对象都都是coonstt类型的的。因此此上面的的表达式式就是试试图将一一个coonstt类型的的对象转转换为非非connst类类型,这这是非法法的。引引用型参参数应该该在能被被定义为为connst的的情况下下,尽量量定义为为connst 。12.将“引引用”作作为函数数返回

11、值值类型的的格式、好好处和需需要遵守守的规则则?格式:类型型标识符符 &函函数名(形形参列表表及类型型说明) /函数体体 好处:在内内存中不不产生被被返回值值的副本本;(注注意:正正是因为为这点原原因,所所以返回回一个局局部变量量的引用用是不可可取的。因因为随着着该局部部变量生生存期的的结束,相相应的引引用也会会失效,产产生ruuntiime errror!注意事事项:(1)不能能返回局局部变量量的引用用。这条条可以参参照Efffecctivve CC+1的的Iteem 331。主主要原因因是局部部变量会会在函数数返回后后被销毁毁,因此此被返回回的引用用就成为为了无无所指的引用用,程序序会进入

12、入未知状状态。 (2)不能能返回函函数内部部neww分配的的内存的的引用。这这条可以以参照EEffeectiive C+1的Ittem 31。虽虽然不存存在局部部变量的的被动销销毁问题题,可对对于这种种情况(返返回函数数内部nnew分分配内存存的引用用),又又面临其其它尴尬尬局面。例例如,被被函数返返回的引引用只是是作为一一个临时时变量出出现,而而没有被被赋予一一个实际际的变量量,那么么这个引引用所指指向的空空间(由由neww分配)就就无法释释放,造造成meemorry lleakk。(3)可以以返回类类成员的的引用,但但最好是是connst。这这条原则则可以参参照Efffecctivve C

13、C+1的的Iteem 330。主主要原因因是当对对象的属属性是与与某种业业务规则则(buusinnesss ruule)相相关联的的时候,其其赋值常常常与某某些其它它属性或或者对象象的状态态有关,因因此有必必要将赋赋值操作作封装在在一个业业务规则则当中。如如果其它它对象可可以获得得该属性性的非常常量引用用(或指指针),那那么对该该属性的的单纯赋赋值就会会破坏业业务规则则的完整整性。(4)流操操作符重重载返回回值申明明为“引引用”的的作用:流操作作符,这两两个操作作符常常常希望被被连续使使用,例例如:ccoutt hhelllo enddl;因此这这两个操操作符的的返回值值应该是是一个仍仍然支持

14、持这两个个操作符符的流引引用。可可选的其其它方案案包括:返回一一个流对对象和返返回一个个流对象象指针。但但是对于于返回一一个流对对象,程程序必须须重新(拷拷贝)构构造一个个新的流流对象,也也就是说说,连续续的两个个操操作符实实际上是是针对不不同对象象的!这这无法让让人接受受。对于于返回一一个流指指针则不不能连续续使用操作作符。因因此,返返回一个个流对象象引用是是惟一选选择。这这个唯一一选择很很关键,它它说明了了引用的的重要性性以及无无可替代代性,也也许这就就是C+语言言中引入入引用这这个概念念的原因因吧。 赋值操操作符=。这个个操作符符象流操操作符一一样,是是可以连连续使用用的,例例如:xx

15、= j = 100;或者者(x=10)=1000;赋赋值操作作符的返返回值必必须是一一个左值值,以便便可以被被继续赋赋值。因因此引用用成了这这个操作作符的惟惟一返回回值选择择。例3i nccludde iint &puut(iint n);intt vaals10;innt eerroor=-1;vvoidd maain()putt(0)=100; /以pput(0)函函数值作作为左值值,等价价于vaals0=10; puut(99)=220; /以以putt(9)函数值值作为左左值,等等价于vvalss9=200; ccouttvvalss0; ccoutt=0 & n=9 ) reetur

16、rn vvalssn; eelsee couutsuubsccrippt eerroor; reeturrn eerroor; (5)在另另外的一一些操作作符中,却却千万不不能返回回引用:+-*/ 四四则运算算符。它它们不能能返回引引用,EEffeectiive C+1的Ittem223详细细的讨论论了这个个问题。主主要原因因是这四四个操作作符没有有sidde eeffeect,因因此,它它们必须须构造一一个对象象作为返返回值,可可选的方方案包括括:返回回一个对对象、返返回一个个局部变变量的引引用,返返回一个个neww分配的的对象的的引用、返返回一个个静态对对象引用用。根据据前面提提到的引引用

17、作为为返回值值的三个个规则,第第2、33两个方方案都被被否决了了。静态态对象的的引用又又因为(a+b) = (c+d)会永远远为trrue而而导致错错误。所所以可选选的只剩剩下返回回一个对对象了。13.“引引用”与与多态的的关系?引用是是除指针针外另一一个可以以产生多多态效果果的手段段。这意意味着,一个基类的引用可以指向它的派生类实例。例4Class A; Class B : Class A.; B b; A& ref = b;14.“引引用”与与指针的的区别是是什么?1) 引用必必须被初初始化,指指针不必必。 22) 引引用初始始化以后后不能被被改变,指指针可以以改变所所指的对对象。 2)

18、不存在在指向空空值的引引用,但但是存在在指向空空值的指指针。指指针通过过某个指指针变量量指向一一个对象象后,对对它所指指向的变变量间接接操作。程程序中使使用指针针,程序序的可读读性差;而引用用本身就就是目标标变量的的别名,对引用的操作就是对目标变量的操作。此外,就是上面提到的对函数传ref和pointer的区别。15.什么么时候需需要“引引用”?流操作作符、赋值值操作符符=的返返回值、拷拷贝构造造函数的的参数、赋赋值操作作符=的的参数、其其它情况况都推荐荐使用引引用。以以上 22-8 参考:htttp:/deevellop.csaai.ccn/cc/NOO000000221.hhtm16.结构

19、构与联合合有和区区别?(1). 结构构和联合合都是由由多个不不同的数数据类型型成员组组成, 但在任任何同一一时刻, 联合合中只存存放了一一个被选选中的成成员(所所有成员员共用一一块地址址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。(2).对于联合的不同成员赋值, 将会对其它成员重写,原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。17.面关关于“联联合”的的题目的的输出?a)i nclludee unnionnintt i;chaar xx2;aa;voidmaiin()a.xx0 = 10; a.x11 = 1;priintff(%d,a.ii);答案:266

20、6 (低低位低地地址,高高位高地地址,内内存占用用情况是是Ox0010AA)b)maiin() uniion /*定义一一个联合合*/ intt i; sttrucct /*在在联合中中定义一一个结构构*/ ccharr fiirstt; chhar seccondd; hallf; nnumbber; nnumbber.i=00x42241; /*联联合成员员赋值*/ priintff(%c%ccn, nuumbeer.hhalff.fiirstt, mmumbber.hallf.ssecoond); nummberr.haalf.firrst=a; /*联合中中结构成成员赋值值*/ nuu

21、mbeer.hhalff.seeconnd=b; pprinntf(%xxn, nuumbeer.ii); geetchh(); 答答案: AB (0x441对应应A,是低低位;OOx422对应B,是高位位)662611 (nnumbber.i和nnumbber.hallf共用用一块地地址空间间)18.关联联、聚合合(Agggreegattionn)以及及组合(Commpossitiion)的区别别?涉及到UMML中的的一些概概念:关关联是表表示两个个类的一一般性联联系,比比如“学学生”和和“老师师”就是是一种关关联关系系;聚合合表示hhas-a的关关系,是是一种相相对松散散的关系系,聚合合类

22、不需需要对被被聚合类类负责,如如下图所所示,用用空的菱菱形表示示聚合关关系:从从实现的的角度讲讲,聚合合可以表表示为:classs AA . cclasss BB A* a; .而组合表示示conntaiins-a的关关系,关关联性强强于聚合合:组合合类与被被组合类类有相同同的生命命周期,组组合类要要对被组组合类负负责,采采用实心心的菱形形表示组组合关系系:实现现的形式式是:cclasss AA. claass B A aa; .27.mmainn 函数数执行以以前,还还会执行行什么代代码?答答案:全全局对象象的构造造函数会会在maain 函数之之前执行行。28.描描述内存存分配方方式以及及它

23、们的的区别?1)从静态态存储区区域分配配。内存在在程序编编译时就就已经分分配好,这这块内存存在程序序的整个个运行期期间都存存在。例例如全局局变量,sstattic 变量。2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。3)从堆上分配,亦称动态内存分配。程序在运行时用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。29.sttrucct 和和 cllasss 的区区别答案:sttrucct

24、 的的成员默默认是公公有的,而而类的成成员默认认是私有有的。sstruuct 和 cclasss 在在其他方方面是功功能相当当的。从从感情上上讲,大大多数的的开发者者感到类类和结构构有很大大的差别别。感觉觉上结构构仅仅象象一堆缺缺乏封装装和功能能的开放放的内存存位,而而类就象象活的并并且可靠靠的社会会成员,它它有智能能服务,有有牢固的的封装屏屏障和一一个良好好定义的的接口。既既然大多多数人都都这么认认为,那那么只有有在你的的类有很很少的方方法并且且有公有有数据(这这种事情情在良好好设计的的系统中中是存在在的!)时时,你也也许应该该使用 strructt 关键键字,否否则,你你应该使使用 ccl

25、asss 关关键字。30.当一一个类AA 中没没有任何何成员变变量与成成员函数数,这时时sizzeoff(A)的值是是多少?答案:如果果不是零零,请解解释一下下编译器器为什么么没有让让它为零零。(AAutoodessk)肯肯定不是是零。举举个反例例,如果果是零的的话,声声明一个个claass A110对对象数组组,而每每一个对对象占用用的空间间是零,这这时就没没办法区区分A0,A11了。值 为1.32.比比较C+中的的4种类类型转换换方式?请参考:hhttpp:/bloog.ccsdnn.neet/wwfwdd/arrchiive/20006/005/330/77637785.asppx,重重

26、点是sstattic_casst, dynnamiic_ccastt和reeintterpprett_caast的的区别和和应用。dynammic_cassts在在帮助你你浏览继继承层次次上是有有限制的的。它不不能被用用于缺乏乏虚函数数的类型型上,它它被用于于安全地地沿着类类的继承承关系向向下进行行类型转转换。如如你想在在没有继继承关系系的类型型中进行行转换,你你可能想想到sttatiic_ccastt44.写一一个在一一个字符符串(nn)中寻寻找一个个子串(m)第第一个位位置的函函数。KMP算法法效率最最好,时时间复杂杂度是(n+m),详见:htttp:/wwww.zzhanngliihai

27、i.coom/bblogg/c_3355_kmmp.hhtmll48.指针针找错题题分析这些面面试题,本本身包含含很强的的趣味性性;而作作为一名名研发人人员,通通过对这这些面试试题的深深入剖析析则可进进一步增增强自身身的内功功。2.找错题题试题11:以下下是引用用片段:voiid ttestt1() /数组组越界ccharr sttrinng110;ccharr* sstr11 = 0112344567789;strrcpyy( sstriing, sttr1 );试题2:以下是是引用片片段:vvoidd teest22()ccharr sttrinng110, sttr110; innt i

28、i;forr(i=0; i110; i+)strr1= a;strrcpyy( sstriing, sttr1 );试题题3:以下下是引用用片段:voiid ttestt3(ccharr* sstr11)chaar sstriing10;if( sttrleen( strr1 ) = 100 )sttrcppy( strringg, sstr11 );解解答:试试题1字字符串sstr11需要111个字字节才能能存放下下(包括括末尾的的00),而而strringg只有110个字字节的空空间,sstrccpy会会导致数数组越界界;试题22,如果果面试者者指出字字符数组组strr1不能能在数组组内结

29、束束可以给给3分;如果面面试者指指出sttrcppy(sstriing,strr1)调调用使得得从 sstr11内存起起复制到到strringg内存起起所复制制的字节节数具有有不确定定性可以以给7分分,在此此基础上上指出库库函数sstrccpy工工作方式式的给110分;对试题题3,iif(sstrllen(strr1) = 10)应改为为if(strrlenn(sttr1) 110),因因为sttrleen的结结果未统统计0所占占用的11个字节节。剖析析:考查查对基本本功的掌掌握(1)字符串串以0结尾尾;(2)对对数组越越界把握握的敏感感度;(33)库函函数sttrcppy的工工作方式式,49

30、.如果果编写一一个标准准strrcpyy函数?总分值值为100,下面面给出几几个不同同得分的的答案:2分以下是是引用片片段:vvoidd sttrcppy( chaar *strrDesst, chaar *strrSrcc )whhilee( (*sttrDeest+ = * strrSrcc+) != 0 );4分以下是是引用片片段:voiid sstrccpy( chhar *sttrDeest, coonstt chhar *sttrSrrc )/将源源字符串串加coonstt,表明明其为输输入参数数,加22分whiile( (*strrDesst+ = * sstrSSrc+) !=

31、 00 );7分以以下是引引用片段段:vooid strrcpyy(chhar *sttrDeest, coonstt chhar *sttrSrrc)/对源地地址和目目的地址址加非00断言,加加3分assserrt( (sttrDeest != NULLL) &(strrSrcc != NUULL) );wwhille( (*sstrDDestt+ = * sttrSrrc+) != 0 );110分以以下是引引用片段段:/为了实实现链式式操作,将将目的地地址返回回,加33分!chhar * sstrccpy( chhar *sttrDeest, coonstt chhar *sttrSrr

32、c )aasseert( (sstrDDestt != NUULL) &(sttrSrrc != NNULLL) ); /对源源地址和和目的地地址加非非0断言言ccharr *aaddrresss = strrDesst;whhilee( (*sttrDeest+ = * strrSrcc+) != 0 );retturnn adddreess; /为了实实现链式式操作,将将目的地地址返回回从从2分到到10分分的几个个答案我我们可以以清楚的的看到,小小小的sstrccpy竟竟然暗藏藏着这么么多玄机机,真不不是盖的的!需要要多么扎扎实的基基本功才才能写一一个完美美的sttrcppy啊!(4)对s

33、ttrleen的掌掌握,它它没有包包括字符符串末尾尾的0。读读者看了了不同分分值的sstrccpy版版本,应应该也可可以写出出一个110分的的strrlenn函数了了, int sstrllen( coonstt chhar *sttr ) /输入参参数coonstt以下下是引用用片段:asssertt( sstrtt != NUULL ); /断断言字符符串地址址非0innt llen=0; /注,一一定要初初始化。while( (*str+) != 0 )len+;return len;试题4:以下是引用片段:void GetMemory( char *p )/内存分配p = (char

34、*) malloc( 100 );void Test( void )char *str = NULL;GetMemory( str );strcpy( str, hello world );printf( str ); 试题5:以下是引用片段:char *GetMemory( void )char p = hello world;return p;void Test( void )char *str = NULL;str = GetMemory();printf( str );试题6:以下是引用片段:void GetMemory( char *p, int num )*p = (char *)

35、 malloc( num );void Test( void )char *str = NULL;GetMemory( &str, 100 );strcpy( str, hello );printf( str );试题7:以下是引用片段:void Test( void )char *str = (char *) malloc( 100 );strcpy( str, hello );free( str );. /省略的其它语句解答:试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完char *str = NULL;G

36、etMemory( str );后的str仍然为NULL;试题5中char p = hello world;return p;的p数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句*p = (char *) malloc( num );后未判断内存是否申请成功,应加上:if ( *p = NULL )./进行申请内存失败处理试题7存在与试题6同样的问题,在执行char *str = (cha

37、r *) malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:str = NULL;试题6的Test函数中也未对malloc的内存进行释放。剖析:试题47考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中5060的错误。但是要完全解答正确,却也绝非易事。 对内存操作作的考查查主要集集中在:(1)指针的的理解;(2)变量的的生存期期及作用用范围;(3)良好的的动态内内存申请请和释放放习惯。再看看下面的一段程序有什么错误:以下是引用片段:swap( int* p1,int* p2 )int *

38、p;*p = *p1;*p1 = *p2;*p2 = *p;在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC+中DEBUG运行时提示错误“Access Violation”。该程序应该改为以下是引用片段:swap( int* p1,int* p2 )int p;p = *p1;*p1 = *p2;*p2 = p;51.h头头文件中中的iffndeef/ddefiine/enddif 的作用用?答:防止该该头文件件被重复复引用。52.ii nccludde 与 i nclludee ffilee.h的区别别?答:前者是是从Sttanddardd Liibraar

39、y的的路径寻寻找和引引用fiile.h,而而后者是是从当前前工作路路径搜寻寻并引用用fille.hh。53.在CC+ 程序中中调用被被C 编编译器编编译后的的函数,为为什么要要加exxterrn “CC”?C+语言言支持函函数重载载,C语语言不支支持函数数重载。CC+提提供了CC连接交交换指定定符号eexteern “C”解决名名字匹配配问题。首先,作为为extternn是C/C+语言中中表明函函数和全全局变量量作用范范围(可可见性)的的关键字字,该关关键字告告诉编译译器,其其声明的的函数和和变量可可以在本本模块或或其它模模块中使使用。通常,在在模块的的头文件件中对本本模块提提供给其其它模块块

40、引用的的函数和和全局变变量以关关键字eexteern声声明。例例如,如如果模块块B欲引引用该模模块A中中定义的的全局变变量和函函数时只只需包含含模块AA的头文文件即可可。这样样,模块块B中调调用模块块A中的的函数时时,在编编译阶段段,模块块B虽然然找不到到该函数数,但是是并不会会报错;它会在在连接阶阶段中从从模块AA编译生生成的目目标代码码中找到到此函数数。extternn CC是连连接申明明(liinkaage decclarratiion),被eexteern C修饰的的变量和和函数是是按照CC语言方方式编译译和连接接的,来来看看CC+中中对类似似C的函函数是怎怎样编译译的:作作为一种种面

41、向对对象的语语言,CC+支支持函数数重载,而而过程式式语言CC则不支支持。函函数被CC+编编译后在在符号库库中的名名字与CC语言的的不同。例例如,假假设某个个函数的的原型为为:vooid fooo( iint x, intt y );该该函数被被C编译译器编译译后在符符号库中中的名字字为_ffoo,而而C+编译器器则会产产生像_fooo_innt_iint之之类的名名字(不不同的编编译器可可能生成成的名字字不同,但但是都采采用了相相同的机机制,生生成的新新名字称称为“mmanggledd naame”)。_foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C+就是靠这种机

42、制来实现函数重载的。例如,在C+中,函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。同样地,C+中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以.来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。未加extern C声明时的连接方式假设在C+中,模模块A的的头文件件如下:/ 模块AA头文件件moodulleA.h#iifnddef

43、MODDULEE_A_H#ddefiine MODDULEE_A_Hinnt ffoo( innt xx, iint y );#eendiif在模块块B中引引用该函函数:/ 模模块B实实现文件件moodulleB.cpppi nclludee mmoduuleAA.hfooo(2,3);加exteern C声明后后的编译译和连接接方式加exteern C声明后后,模块块A的头头文件变变为:/ 模模块A头头文件modduleeA.hh#iffndeef MMODUULE_A_HH#deefinne MMODUULE_A_HHextternn CC iint fooo( iint x, intt y );#enddif在模块B的的实现文文件中仍仍然调用用fooo( 22,3 ),其其结果是是:(11)模块块A编译译生成ffoo的的目标代代码时,没没有对其其名字进进行特殊殊处理,采采用了

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文献 > 管理手册

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁