华为C++面试宝典知识讲解.doc
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《华为C++面试宝典知识讲解.doc》由会员分享,可在线阅读,更多相关《华为C++面试宝典知识讲解.doc(64页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、Good is good, but better carries it.精益求精,善益求善。华为C+面试宝典-变量static和const关键字的作用static关键字至少有下列n个作用:(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;(
2、5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。const关键字至少有下列n个作用:(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;(5)对于
3、类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:constclassAoperator*(constclassA&a1,constclassA&a2);operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:classAa,b,c;(a*b)=c;/对a*b的结果赋值操作(a*b)=c显然不符合编程者的初衷,也没有任何意义。函数体中的指针或引用常量不能被返回Char*func(void)charstr=”HelloWord”;/这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉return
4、str;函数体内的指针变量并不会随着函数的消亡而自动释放函数一个内存拷贝函数的实现体void*memcpy(void*pvTo,constvoid*pvFrom,size_tsize)assert(pvTo!=NULL)&(pvFrom!=NULL);byte*pbTo=(byte*)pvTo;/防止地址被改变byte*pbFrom=(byte*)pvFrom;while(size-0)pbTo+=pbForm+;returnpvTo;C+函数中值的传递方式有三种方式:值传递(Passbyvalue)、指针传递(Passbypointer)、引用传递(Passbyreference)voidf
5、un(charc)/passbyvaluevoidfun(char*str)/passbypointervoidfun(char&str)/passbyreference如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构函数的类型不能省略,就算没有也要加个void判断处理器存放数据的类型请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1解答:intcheckCPU()unionwinta;charb;c;c.a=1;return(c.b=1);剖析:嵌入式系统开发者应该对Little-endian和Big
6、-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地址存放内容0x40000x340x40010x12而在Big-endian模式CPU内存中的存放方式则为:内存地址存放内容0x40000x120x40010x3432bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地
7、址存放内容0x40000x780x40010x560x40020x340x40030x12而在Big-endian模式CPU内存中的存放方式则为:内存地址存放内容0x40000x120x40010x340x40020x560x40030x78联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。设计atoi函数intatoi(char*s)intatoi(constchar*nptr);函数说明atoi()会扫描参数nptr字符
8、串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(0)才结束转换,并将结果返回。返回值返回转换后的整型数。#include#includeintmyAtoi(constchar*s)intresult=0;intflag=1;inti=0;while(isspace(si)i+;if(si=-)flag=-1;i+;if(si=+)i+;while(si!=0)if(si9)|(si2-3-4-5通过反转后成为5-4-3-2-1。最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已
9、经存储的指针往后面继续遍历。源代码如下:structlinkaintdata;linka*next;voidreverse(linka*&head)if(head=NULL)return;linka*pre,*cur,*ne;pre=head;cur=head-next;while(cur)ne=cur-next;cur-next=pre;pre=cur;cur=ne;head-next=NULL;head=pre;还有一种利用递归的方法。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。源代码如下。不过这个方法有一个缺点,就是在反转后的最后一个结点会形成一个环,所以必须将函数
10、的返回的节点的next域置为NULL。因为要改变head指针,所以我用了引用。算法的源代码如下:linka*reverse(linka*p,linka*&head)if(p=NULL|p-next=NULL)head=p;returnp;elselinka*tmp=reverse(p-next,head);tmp-next=p;returnp;双向链表有双向循环链表结点定义为:structnodeintdata;structnode*front,*next;有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中data值相同的结点删除BOOLDeteleNo
11、de(Node*pHeader,DataTypeValue)if(pHeader=NULL)return;BOOLbRet=FALSE;Node*pNode=pHead;while(pNode!=NULL)if(pNode-data=Value)if(pNode-front=NULL)pHeader=pNode-next;pHeader-front=NULL;elseif(pNode-next!=NULL)pNode-next-front=pNode-front;pNode-front-next=pNode-next;Node*pNextNode=pNode-next;deletepNode;
12、pNode=pNextNode;bRet=TRUE;/不要break或return,删除所有elsepNode=pNode-next;returnbRet;voidDE(Node*pHeadA,Node*pHeadB)if(pHeadA=NULL|pHeadB=NULL)return;Node*pNode=pHeadA;while(pNode!=NULL)if(DeteleNode(pHeadB,pNode-data)if(pNode-front=NULL)pHeadA=pNode-next;pHeadA-front=NULL;elsepNode-front-next=pNode-next;i
13、f(pNode-next!=NULL)pNode-next-front=pNode-front;Node*pNextNode=pNode-next;deletepNode;pNode=pNextNode;elsepNode=pNode-next;循环链表怎么判断链表中是否有环?boolCircleInList(Link*pHead)if(pHead=NULL|pHead-next=NULL)/无节点或只有一个节点并且无自环return(false);if(pHead-next=pHead)/自环return(true);Link*pTemp1=pHead;/step1Link*pTemp=pH
14、ead-next;/step2while(pTemp!=pTemp1&pTemp!=NULL&pTemp-next!=NULL)pTemp1=pTemp1-next;pTemp=pTemp-next-next;if(pTemp=pTemp1)return(true);return(false);类构造函数与析构函数派生类的构造函数应在初始化表里调用基类的构造函数;派生类和基类的析构函数应加Virtual关键字。不要小看构造函数和析构函数,其实编起来还是不容易。#includeclassBasepublic:virtualBase()coutBaseendl;classDerived:publi
15、cBasepublic:virtualDerived()coutDerivedendl;voidmain(void)Base*pB=newDerived;/upcastdeletepB;输出结果为:DerivedBase如果析构函数不为虚,那么输出结果为Base2. 指针和引用什么是“引用”?申明和使用“引用”要注意哪些问题?答:引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变
16、量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。将“引用”作为函数参数有哪些特点?传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传
17、递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用*指针变量名的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。在什么时候需要使用“常引用”?如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const类型标识符&引用名=目标变量名;例1inta;constint&ra=a;ra=1;/错误a=1;/正确例2stringfoo
18、();voidbar(string&s);那么下面的表达式将是非法的:bar(foo();bar(helloworld);原因在于foo()和helloworld串都会产生一个临时对象,而在C+中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。引用型参数应该在能被定义为const的情况下,尽量定义为const。将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?格式:类型标识符&函数名(形参列表及类型说明)/函数体好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。因
19、为随着该局部变量生存期的结束,相应的引用也会失效,产生runtimeerror!注意事项:(1)不能返回局部变量的引用。这条可以参照EffectiveC+1的Item31。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了无所指的引用,程序会进入未知状态。(2)不能返回函数内部new分配的内存的引用。这条可以参照EffectiveC+1的Item31。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放
20、,造成memoryleak。(3)可以返回类成员的引用,但最好是const。这条原则可以参照EffectiveC+1的Item30。主要原因是当对象的属性是与某种业务规则(businessrule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。(4)流操作符重载返回值申明为“引用”的作用:流操作符,这两个操作符常常希望被连续使用,例如:couthelloendl;因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华为 C+ 面试 宝典 知识 讲解
![提示](https://www.deliwenku.com/images/bang_tan.gif)
限制150内