您好,欢迎访问三七文档
1.引用与指针有什么区别?1)引用必须被初始化,指针不必。2)引用初始化以后不能被改变,指针可以改变所指的对象。3)不存在指向空值的引用,但是存在指向空值的指针。2.堆栈溢出一般是由什么原因导致的?没有回收垃圾资源。3.什么函数不能声明为虚函数?constructor函数不能声明为虚函数。4.写出floatx与“零值”比较的if语句。if(x0.000001&&x-0.000001)5.不能做switch()的参数类型是:switch的参数不能为实型6.头文件中的ifndef/define/endif干什么用?预处理答:防止头文件被重复引用7.#includefilename.h和#includefilename.h有什么区别?答:对于#includefilename.h,编译器从标准库路径开始搜索filename.h对于#includefilename.h,编译器从用户的工作路径开始搜索filename.h8.在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”声明?答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被externC修饰的变量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调用C函数。C++提供了一个C连接交换指定符号extern“C”来解决这个问题。9.charstr1[]=abc;charstr2[]=abc;constcharstr3[]=abc;constcharstr4[]=abc;constchar*str5=abc;constchar*str6=abc;char*str7=abc;char*str8=abc;cout(str1==str2)endl;cout(str3==str4)endl;cout(str5==str6)endl;cout(str7==str8)endl;结果是:0011str1,str2,str3,str4是数组变量,它们有各自的内存空间;而str5,str6,str7,str8是指针,它们指向相同的常量区域。10.main(){inta[5]={1,2,3,4,5};int*ptr=(int*)(&a+1);printf(%d,%d,*(a+1),*(ptr-1));}答:2,5*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5。&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)。int*ptr=(int*)(&a+1);则ptr实际是&(a[5]),也就是a+5原因如下:&a是数组指针,其类型为int(*)[5];而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同;a是长度为5的int数组指针,所以要加5*sizeof(int)。所以ptr实际是a[5]。但是prt与(&a+1)类型是不一样的(这点很重要),所以prt-1只会减去sizeof(int*)。a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]。11.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;答:有两种解法,一种用算术算法,一种用^(异或)a=a+b;b=a-b;a=a-b;ora=a^b;//只能对int,char..b=a^b;a=a^b;ora^=b^=a;12.列举几种进程的同步机制,并比较其优缺点。答:原子操作、信号量机制、自旋锁、管程、会合、分布式系统13.进程死锁的原因和4个必要条件答:资源竞争及进程推进顺序非法;互斥、请求保持、不可剥夺、环路14.要对绝对地址0x100000赋值,我们可以用(unsignedint*)0x100000=1234;那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?答:*((void(*)())0x100000)();首先要将0x100000强制转换成函数指针,即:(void(*)())0x100000。然后再调用它:*((void(*)())0x100000)();用typedef可以看得更直观些:typedefvoid(*)()voidFuncPtr;*((voidFuncPtr)0x100000)();15.unsignedchar*p1;unsignedlong*p2;p1=(unsignedchar*)0x801000;p2=(unsignedlong*)0x810000;请问p1+5=______;p2+5=______;答案:801005;810014。不要忘记了这个是16进制的数字,p2要加20变为16进制就是1416、设有以下说明和定义:typedefunion{longi;intk[5];charc;}DATE;structdata{intcat;DATEcow;doubledog;}too;DATEmax;则语句printf(%d,sizeof(too)+sizeof(max));的执行结果是:______答:DATE是一个union,变量公用空间.里面最大的变量类型是int[5],占用20个字节.所以它的大小是20data是一个struct,每个变量分开占用空间.依次为int4+DATE20+double8=32.所以结果是20+32=52.当然...在某些16位编辑器下,int可能是2字节,那么结果是int2+DATE10+double8=20试题1:Voidtest1(){charstring[10];char*str1=0123456789;strcpy(string,str1);}试题2:Voidtest2(){charstring[10],str1[10];for(I=0;I10;I++){str1[i]='a';}strcpy(string,str1);}试题3:Voidtest3(char*str1){charstring[10];if(strlen(str1)=10){strcpy(string,str1);}}在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“AccessViolation”。该程序应该改为:解答:test1:字符串str1需要11个字节才能存放下(包括末尾的'\0'),而string只有10个字节的空间,strcpy会导致数组越界test2:如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分test3:if(strlen(str1)=10)应改为if(strlen(str1)10),因为strlen的结果未统计'\0'所占用的1个字节剖析:考查对基本功的掌握:(1)字符串以'\0'结尾;(2)对数组越界把握的敏感度;(3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:2分voidstrcpy(char*strDest,char*strSrc){while((*strDest++=*strSrc++)!='\0');}4分voidstrcpy(char*strDest,constchar*strSrc)//将源字符串加const,表明其为输入参数,加2分{while((*strDest++=*strSrc++)!='\0');}7分voidstrcpy(char*strDest,constchar*strSrc){//对源地址和目的地址加非0断言,加3分assert((strDest!=NULL)&&(strSrc!=NULL));while((*strDest++=*strSrc++)!='\0');}10分//为了实现链式操作,将目的地址返回,加3分!char*strcpy(char*strDest,constchar*strSrc){assert((strDest!=NULL)&&(strSrc!=NULL));char*address=strDest;while((*strDest++=*strSrc++)!='\0');returnaddress;}(4)对strlen的掌握,它没有包括字符串末尾的'\0'。读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为intstrlen(constchar*str)//输入参数const{assert(strt!=NULL);//断言字符串地址非0intlen;while((*str++)!='\0'){len++;}returnlen;}试题4:voidGetMemory(char*p){p=(char*)malloc(100);}voidTest(void){char*str=NULL;GetMemory(str);strcpy(str,helloworld);printf(str);}试题5:char*GetMemory(void){charp[]=helloworld;returnp;}voidTest(void){char*str=NULL;str=GetMemory();printf(str);}试题6:voidGetMemory(char**p,intnum){*p=(char*)malloc(num);}voidTest(void){char*str=NULL;GetMemory(&str,100);strcpy(str,hello);printf(str);}试题7:voidTest(void){char*str=(char*)malloc(100);strcpy(str,hello);free(str);//省略的其它语句}解答:试题4传入中GetMemory(char*p)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完char*str=NULL;GetMemory(str);后的str仍然为NULL;试题5中charp[]=helloworld;returnp;的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句*p=(char*)malloc(num);后未判断内存是否申请成功,应加上:if(*p==NULL){...//进行申请内存失败处理}试题7存在与试题6同样的问题,在执行char*str=(char*)malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:str=NULL;试题6的Test函数中也未对malloc的内存进行释放。剖析:试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。对内存操作的考查主要集中在:(1)指针的理解;(2)变量的生存期及作用范围;(3)良好的动态内存申请和释放习惯。再看看下面的一段程序有什么错误:swap(int*p1,int*p2){int*p;*p=*p1;*p1=*p2;*p2=*p;}swap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}2.内功题试题1:分别给出BOOL,int,float,指针变量与“零值”比较的if语句(假设变量名为var)解答:BOOL型变量:if(!var)int型变量:if(
本文标题:IT面试题整合
链接地址:https://www.777doc.com/doc-5061969 .html