('c语言面试题集(完整版)试题1:C语言面试题一——华为篇1.static有什么用途?(请至少说明两种)1)限制变量的作用域2)设置变量的存储域(堆,主动分配内存也是堆)2.引用与指针有什么区别?1)引用必须被初始化,指针不必。2)引用初始化以后不能被改变,指针可以改变所指的对象。3)不存在指向空值的引用,但是存在指向空值的指针。3.描述实时系统的基本特性在特定时间内完成特定的任务,实时性与可靠性4.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?全局变量储存在静态数据库,局部变量在栈5.什么是平衡二叉树?左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于16.堆栈溢出一般是由什么原因导致的?没有回收垃圾资源7.什么函数不能声明为虚函数?constructor(构造函数)8.冒泡排序算法的时间复杂度是什么?(其它排序算法的时间复杂度)O(n^2)9.写出floatx与“零值”比较的if语句。if(x>0.000001&&x<-0.000001)10.Internet采用哪种网络协议?该协议的主要层次结构?tcp/ip应用层/传输层/网络层/数据链路层/物理层11.Internet物理地址和IP地址转换采用什么协议?ARP(AddressResolutionProtocol)(地址解析協議)18.IP地址的编码分为哪俩部分?IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。19.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。循环链表,用取余操作做#include#defineNULL0#defineTYPEstructstu#defineLENsizeof(structstu)structstu{intdata;structstunext;};TYPEline(intn){intsum=1;structstuhead,pf,pb;inti;for(i=0;idata=sum;if(i==0)pf=head=pb;elsepf->next=pb;if(i==(n-1))pb->next=head;elsepb->next=NULL;pf=pb;sum++;}return(head);}main(){intM,N,x,i;structstup,q;printf("pleasescanfMandN(Mnext;}q=p->next;printf("%d\\n",q->data);p->next=p->next->next;p=p->next;free(q);x--;}getch();}20.不能做switch()的参数类型是:switch的参数不能为实型。(只能是intchar)试题2:1.-1,2,7,28,,126请问28和126中间那个数是什么?为什么?第一题的答案应该是4^3-1=63规律是n^3-1(当n为偶数0,2,4)n^3+1(当n为奇数1,3,5)答案:632.用两个栈实现一个队列的功能?要求给出算法和思路!设2个栈为A,B,一开始均为空.入队:将新元素push入栈A;出队:(1)判断栈B是否为空;(2)如果不为空,则将栈A中所有元素依次pop出并push到栈B;(3)将栈B的栈顶元素pop出;这样实现的队列入队和出队的平摊复杂度都还是O(1),比上面的几种方法要好。3.在c语言库函数中将一个字符转换成整型的函数是atol()吗,这个函数的原型是什么?函数名:atol功能:把字符串转换成长整型数用法:longatol(constcharnptr);程序例:#include#includeintmain(void){longl;charstr="98765432";l=atol(lstr);printf("string=%sinteger=%ld\\n",str,l);return(0);}4.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?c用宏定义,c++用inline5.直接链接两个信令点的一组链路称作什么?PPP点到点连接6.接入网用的是什么接口?TCP/IP7.voip都用了那些协议?RTCP8.软件测试都有那些种类?黑盒:针对系统功能的测试白合:测试函数功能,各函数接口9.确定模块的功能和模块的接口是在软件设计的那个队段完成的?概要设计阶段11.unsignedcharp1;unsignedlongp2;p1=(unsignedchar)0x801000;p2=(unsignedlong)0x810000;请问p1+5=?;p2+5=?;答:p1+5=0x801005;p2+5=0x810020;二.选择题:1.Ethternet链接到Internet用到以下那个协议?DA.HDLC;B.ARP;C.UDP;D.TCP;E.ID2.属于网络层协议的是:BCA.TCP;B.IP;C.ICMP;D.X.253.Windows消息调度机制是:cA.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;4.unsignedshorthash(unsignedshortkey){return(key>>4)%256}请问hash(16),hash(256)的值分别是:AA.1.16;B.8.32;C.4.16;D.1.32三.找错题:1.请问下面程序有什么错误?inta[60][250][1000],i,j,k;for(k=0;k<1000;k++)for(j=0;j<250;j++)for(i=0;i<60;i++)a[i][j][k]=0;把循环语句内外换一下2.#defineMax_CB500voidLmiQueryCSmd(StructMSgCBpmsg){unsignedcharucCmdNum;......for(ucCmdNum=0;ucCmdNumMax_GT_Length){returnGT_Length_ERROR;}.......}试题3:华为全套完整试题高级题1、已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然后删除。slnodetypeDelete(slnodetypeHead,intkey){}中if(Head->number==key){Head=Pointer->next;free(Pointer);break;}Back=Pointer;Pointer=Pointer->next;if(Pointer->number==key){Back->next=Pointer->next;free(Pointer);break;}voiddelete(Nodep){if(Head=Node)while(p)}2、有一个16位的整数,每4位为一个数,写函数求他们的和。解释:整数1101010110110111和1101+0101+1011+0111感觉应该不难,当时对题理解的不是很清楚,所以写了一个函数,也不知道对不对。疑问:既然是16位的整数,1101010110110111是2进制的,那么函数参数怎么定义呢,请大虾指教。答案:用十进制做参数,计算时按二进制考虑。/n就是16位的数,函数返回它的四个部分之和charSumOfQuaters(unsignedshortn){charc=0;inti=4;do{c+=n&15;n=n>>4;}while(--i);returnc;}3、有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.(华为)#includeintmain(){inta[]={10,6,9,5,2,8,4,7,1,3};intlen=sizeof(a)/sizeof(int);inttemp;for(inti=0;inext;while(q!=NULL){r=q->next;q->next=p;p=q;q=r;}head->next=NULL;head=p;returnhead;}2、写出程序删除链表中的所有接点voiddel_all(nodehead){nodep;while(head!=NULL){p=head->next;free(head);head=p;}cout<<"释放空间成功!"<intmain(void){inta,b,c,d;a=10;b=a++;c=++a;d=10a++;printf("b,c,d:%d,%d,%d",b,c,d);return0;}答:10,12,1205、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?答:1)全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。2)从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。3)static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件综上所述:static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝6、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区)中,动态申请数据存在于(堆)中。7、设有以下说明和定义:typedefunion{longi;intk[5];charc;}DATE;structdata{intcat;DATEcow;doubledog;}too;DATEmax;则语句printf("%d",sizeof(structdata)+sizeof(max));的执行结果是:考点:区别struct与union.(一般假定在32位机器上)答:DATE是一个union,变量公用空间.里面最大的变量类型是int[5],占用20个字节.所以它的大小是20.data是一个struct,每个变量分开占用空间.依次为int4+DATE20+double8=32.所以结果是20+32=52.当然...在某些16位编辑器下,int可能是2字节,那么结果是int2+DATE10+double8=208、队列和栈有什么区别?队列先进先出,栈后进先出9、写出下列代码的输出内容#includeintinc(inta){return(++a);}intmulti(inta,intb,intc){return(c=ab);}typedefint(FUNC1)(intin);typedefint(FUNC2)(int,int,int);voidshow(FUNC2fun,intarg1,intarg2){FUNC1p=&inc;inttemp=p(arg1);fun(&temp,&arg1,arg2);printf("%dn",arg2);}main(){inta;//局部变量a为0;show(multi,10,&a);return0;}答:11010、请找出下面代码中的所有错误(题目不错,值得一看)说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”#include"string.h"main(){charsrc="hello,world";chardest=NULL;intlen=strlen(src);dest=(char)malloc(len);chard=dest;chars=src[len];while(len--!=0)d++=s--;printf("%s",dest);return0;}答:方法1:一共有4个错误;intmain(){charsrc="hello,world";intlen=strlen(src);chardest=(char)malloc(len+1);//要为分配一个空间chard=dest;chars=&src[len-1];//指向最后一个字符while(len--!=0)d++=s--;d=0;//尾部要加’\\0’printf("%sn",dest);free(dest);//使用完,应当释放空间,以免造成内存汇泄露dest=NULL;//防止产生野指针return0;}方法2:(方法一需要额外的存储空间,效率不高.)不错的想法#include#includemain(){charstr[]="hello,world";intlen=strlen(str);chart;for(inti=0;i>N==1);4.unsignedintintvert(unsignedintx,intp,intn)实现对x的进行转换,p为起始转化位,n为需要转换的长度,假设起始点在右边.如x=0b00010001,p=4,n=3转换后x=0b01100001答:unsignedintintvert(unsignedintx,intp,intn)//假定p=4,n=3{unsignedint_t=0;unsignedint_a=1;for(inti=0;i(Y)?(Y):(X))//结尾没有;2、嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。答:while(1){}或者for(;;)//前面那个较好3、关键字static的作用是什么?答:1)定义静态局部变量,作用域从函数开始到结束.2)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;3)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝4、关键字const有什么含意?答:1)表示常量不可以修改的变量。2)可以修饰参数,作为输入参数.3)修饰函数,防止以外的改动.4)修饰类的成员函数,不改变类中的数据成员.5、关键字volatile有什么含意?并举出三个不同的例子?答:提示编译器对象的值可能在编译器未监测到的情况下改变。例子:硬件时钟;多线程中被多个任务共享的变量等6.int(s[10])(int)表示的是什么啊int(s[10])(int)函数指针数组,每个指针指向一个intfunc(intparam)的函数。试题10:1.有以下表达式:inta=248;b=4;intconstc=21;constintd=&a;intconste=&b;intconstfconst=&a;请问下列表达式哪些会被编译器禁止?为什么?答:c=32;d=&b;d=43;e=34;e=&a;f=0x321f;c这是个什么东东,禁止d说了是const,禁止e=&a说了是const禁止constfconst=&a;禁止2.交换两个变量的值,不使用第三个变量。即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;3.c和c++中的struct有什么不同?答:c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private.4.#include#includevoidgetmemory(charp){p=(char)malloc(100);}intmain(){charstr=NULL;getmemory(str);strcpy(p,"helloworld");printf("%s/n",str);free(str);return0;}答:程序崩溃,getmemory中的malloc不能返回动态内存,free()对str操作很危险5.charszstr[10];strcpy(szstr,"0123456789");产生什么结果?为什么?答;正常输出,长度不一样,会造成非法的OS,覆盖别的内容.6.列举几种进程的同步机制,并比较其优缺点。答:原子操作信号量机制自旋锁管程,会合,分布式系统7.进程之间通信的途径答共享存储系统消息传递系统管道:以文件系统为基础试题11:面试经典试题1编程基础1.1基本概念1.const的理解:constchar,charconst,charconst的区别问题几乎是C++面试中每次都会有的题目。事实上这个概念谁都有只是三种声明方式非常相似很容易记混。Bjarne在他的TheC++ProgrammingLanguage里面给出过一个助记的方法:把一个声明从右向左读。charconstcp;(读成pointerto)cpisaconstpointertocharconstcharp;pisapointertoconstchar;charconstp;同上因为C++里面没有const的运算符,所以const只能属于前面的类型。2.c指针intp[n];-----指针数组,每个元素均为指向整型数据的指针。int(p)[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。p+1;指向数组的第二个元素(p+0)+1;指向数组的第二个元素p+1指针指向下一个数组的首元素intp();----------函数带回指针,指针指向返回的值。int(p)();------p为指向函数的指针。3.数组越界问题(这个题目还是有点小险的)下面这个程序执行后会有什么错误或者效果:#defineMAX255intmain(){unsignedcharA[MAX],i;for(i=0;i<=MAX;i++)A[i]=i;}解答:MAX=255,数组A的下标范围为:0..MAX-1,这是其一,其二当i循环到255时,循环内执行:A[255]=255;这句本身没有问题,但是返回for(i=0;i<=MAX;i++)语句时,由于unsignedchar的取值范围在(0..255),i++以后i又为0了..无限循环下去.注:char类型为一个字节,取值范围是[-128,127],unsignedchar[0,255]4.C++:memset,memcpy和strcpy的根本区别?答:#include"memory.h"memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为\'\'或\'\';例:chara[100];memset(a,\'\',sizeof(a));memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:chara[100],b[50];memcpy(b,a,sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。strcpy就只能拷贝字符串了,它遇到\'\\0\'就结束拷贝;例:chara[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个\'\\0\'之前)是否超过50位,如超过,则会造成b的内存地址溢出。strcpy原型:externcharstrcpy(chardest,charsrc);{ASSERT((dest!=NULL)&&(src!=NULL));Charaddress=dest;While((dest++=src++)!=’\\0’)Continue;Returndest;}用法:#include功能:把src所指由NULL结束的字符串复制到dest所指的数组中。说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。memcpy原型:externvoidmemcpy(voiddest,voidsrc,unsignedintcount);{ASSERT((dest!=NULL)&&(src!=NULL));ASSERT((dest>src+count)(src>dest+count));//防止内存重叠,也可以用restrict修饰指针Bytebdest=(Byte)dest;Bytebsrc=(Byte)src;While(count-->0)bdest++=bsrc++;Returndest;}用法:#include功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。Memset原型:externvoidmemset(voidbuffer,charc,intcount);用法:#include功能:把buffer所指内存区域的前count个字节设置成字符c。说明:返回指向buffer的指针。5.ASSERT()是干什么用的答:ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE(0),程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:......ASSERT(n!=0);k=10/n;......ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。assert()的功能类似,它是ANSIC标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。6.system("pause");作用?答:系统的暂停程序,按任意键继续,屏幕会打印,"按任意键继续。。。。。"省去了使用getchar();7.请问C++的类和C里面的struct有什么区别?答:c++中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有c里面的struct没有成员函数,不能继承,派生等等.8.请讲一讲析构函数和虚函数的用法和作用?答:析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。只是在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。另:析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,虚拟函数的功能是使子类可以用同名的函数对父类函数进行覆盖,并且在调用时自动调用子类覆盖函数,如果是纯虚函数,则纯粹是为了在子类覆盖时有个统一的命名而已。注意:子类重新定义父类的虚函数的做法叫覆盖,override,而不是overload(重载),重载的概念不属于面向对象编程,重载指的是存在多个同名函数,这些函数的参数表不同..重载是在编译期间就决定了的,是静态的,因此,重载与多态无关.与面向对象编程无关.含有纯虚函数的类称为抽象类,不能实例化对象,主要用作接口类//9.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?答;全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。全局变量在main函数调用后,就开始分配,静态变量则是在main函数前就已经初始化了。局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)10.8086是多少位的系统?在数据总线上是怎么实现的?答:8086系统是16位系统,其数据总线是20位。12程序设计1.编写用C语言实现的求n阶阶乘问题的递归算法:答:longintfact(intn){If(n==0n==1)Return1;ElseReturnnfact(n-1);}2.二分查找算法:1)递归方法实现:intBSearch(elemtypea[],elemtypex,intlow,inthigh)/在下届为low,上界为high的数组a中折半查找数据元素x/{intmid;if(low>high)return-1;mid=(low+high)/2;if(x==a[mid])returnmid;if(x2解:非递归算法:intf(intn){inti,s,s1,s2;s1=1;/s1用于保存f(n-1)的值/s2=1;/s2用于保存f(n-2)的值/s=1;for(i=3;i<=n;i++){s=s1+s2;s2=s1;s1=s;}return(s);}递归算法:Intf(intn){If(n==1n==2)Rerurn1;ElseRerutnf(n-1)+f(n-2);}4.交换两个数,不用第三块儿内存:答:inta=……;intb=……;a=a+b;b=a-b;a=a-b;5.冒泡排序:答:voidBubbleSort(elemtypex[],intn)//时间复杂度为0(nn);{inti,j;elemtypetemp;for(i=1;ix[j+1].key){temp=x[j];x[j]=x[j+1];x[j+1]=temp;}}}//补充一个改进的冒泡算法:voidBubbleSort(elemtypex[],intn){Inti,j;BOOLexchange;//记录交换标志for(i=1;i=i;--j){If(x[j]>x[j+1]){x[0]=x[j];X[j]=x[j+1];X[j+1]=x[0];Exchange=true;//发生了交换,设置标志为真.}}if(!Exchange)//为发生替换,提前终止算法return;}}6.c语言文件读写#include"stdio.h"main(){FILEfp;charch,filename[10];scanf("%s",filename);if((fp=fopen(filename,"w")==NULL){printf("cann\'topenfilen");exit(0);}ch=getchar();while(ch!=\'#\'){fputc(ch,fp);putchar(ch);ch=getchar();}fclose(fp);}7.winsocket编程//这个不错//服务器代码#include#includevoidmain(){WORDwVersionRequested;//版本号WSADATAwsaData;//数据interr;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if(err!=0){return;}if(LOBYTE(wsaData.wVersion)!=1HIBYTE(wsaData.wVersion)!=1){WSACleanup();return;}SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);//建立套接字SOCKADDR_INaddrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);bind(sockSrv,(SOCKADDR)&addrSrv,sizeof(SOCKADDR));//绑定端口listen(sockSrv,5);//转换socket套接子为侦听套接子SOCKADDR_INaddrClient;intlen=sizeof(SOCKADDR);while(1)//无限循环{SOCKETsockConn=accept(sockSrv,(SOCKADDR)&addrClient,&len);charsendBuf[100];sprint(sendBuf,"Welcome%stohttp://www.sunxin.org",inet_ntoa(addrClient.sin_addr));send(sockConn,sendBuf,strlen(sendBuf)+1,0);charrecvBuf[100];recv(sockConn,recvBuf);printf("%sn",recvBuf);closesocket(sockConn);WSACleanup();}}注:这是Server端;File->New->Win32ConsoleApplication,工程名:TcpSrv;然后,File->New->C++SourceFile,文件名:TcpSrv;在该工程的Setting的Link的Object/librarymodules项要加入ws2_32.lib#include#includevoidmain(){WORDwVersionRequested;WSADATAwsaData;interr;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);//启动winsockDllif(err!=0){return;}if(LOBYTE(wsaData.wVersion)!=1HIBYTE(wsaData.wVersion)!=1){WSACleanup();return;}SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_INaddrSrv;addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);connect(sockClient,(SOCKADDR)&addrSrv,sizeof(SOCKADDR));charrecvBuf[100];recv(sockClient,recvBuf,100,0);printf("%sn",recvBuf);send(sockClient,"Thisiszhangsan",strlen("Thisiszhangsan")+1,0);closesocket(sockClient);WSACleanup();}注:这是Client端;File->New->Win32ConsoleApplication,工程名:TcpClient;然后,File->New->C++SourceFile,文件名:TcpClient;同理,在该工程的Setting的Link的Object/librarymodules项要加入ws2_32.lib8.类的知识(非常不错的一道题目)..C++#includeclasshuman{public:human(){human_num++;};//默认构造函数staticinthuman_num;//静态成员~human(){human_num--;print();}voidprint()//{cout<<"humannumis:"<=-EPSINON)&&(x<=EPSINON)指针变量:if(var==NULL)剖析:考查对0值判断的“内功”,BOOL型变量的0判断完全可以写成if(var==0),而int型变量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。一般的,如果想让if判断一个变量的“真”、“假”,应直接使用if(var)、if(!var),表明其为“逻辑”判断;如果用if判断一个数值型变量(short、int、long等),应该用if(var==0),表明是与0进行“数值”上的比较;而判断指针则适宜用if(var==NULL),这是一种很好的编程习惯。浮点型变量并不精确,所以不可将float变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。如果写成if(x==0.0),则判为错,得0分。试题2:以下为WindowsNT下的32位C++程序,请计算sizeof的值voidFunc(charstr[100]){sizeof(str)=?}voidp=malloc(100);sizeof(p)=?解答:sizeof(str)=4sizeof(p)=4剖析:Func(charstr[100])函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。数组名的本质如下:(1)数组名指代一种数据结构,这种数据结构就是数组;例如:charstr[10];cout<13、将身份证号码为440401430103082的记录在两个表中的申请状态均改为07updateg_cardapplydetailsetg_state=\'07\'whereg_idcard=\'440401430103082\'updateAsetg_state=\'07\'fromg_cardapplyAinnerjoing_cardapplydetailBonA.g_applyno=B.g_applynowhereB.g_idcard=\'440401430103082\'4、删除g_cardapplydetail表中所有姓李的记录deletefromg_cardapplydetailwhereg_namelike\'李%\'3、将身份证号码为440401430103082的记录在两个表中的申请状态均改为07updateg_cardapplydetailsetg_state=\'07\'whereg_idcard=\'440401430103082\'updateAsetg_state=\'07\'fromg_cardapplyAinnerjoing_cardapplydetailBonA.g_applyno=B.g_applynowhereB.g_idcard=\'440401430103082\'5、SQL问答题:/Selectg_cardapply.g_applydateFromg_cardapply,g_cardapplydetailWhereg_cardapply.g_applyno=g_cardapplydetail.g_applynoAndg_cardapplydetail.g_idcard=\'440401430103082\'//SelectFrom(selectcount()g_count,g_idcardFromg_cardapplydetailGroupbyg_idcard)aWherea.g_count>=2//Updateg_cardapplysetg_state=\'07\'whereg_applynoin(selectdistinctg_applynofromg_cardapplydetailwhereg_idcard=\'440401430103082\')updateg_cardapplydetailsetg_state=\'07\'whereg_idcard=\'440401430103082\'/Deletefromg_cardapplydetailWhereg_namelike\'李%\'/试题12:金山公司几道面试题1、InC++,there\'refourtypeofCastingOperators,pleaseenumerateandexplainthemespeciallythedifference.解析:C++类型转换问题答案:reinterpret_cast,static_cast,const_cast,dynamic_caststatic_cast数制转换dynamic_cast用于执行向下转换和在继承之间的转换const_cast去掉constreinterpret_cast用于执行并不安全的orimplmentation_dependent类型转换2、以下代码有什么问题,如何修改?#include#includeusingnamespacestd;voidprint(vector);intmain(){vectorarray;array.push_back(1);array.push_back(6);array.push_back(6);array.push_back(3);//删除array数组中所有的6vector::iteratoritor;vector::iteratoritor2;itor=array.begin();for(itor=array.begin();itor!=array.end();){if(6==itor){itor2=itor;array.erase(itor2);}itor++;}print(array);return0;}voidprint(vectorv){cout<<"nvectorsizeis:"<::iteratorp=v.begin();}我的答案是,迭代器问题,只能删除第一个6,以后迭代器就失效了,不能删除之后的元素。但我不知道怎么改voidprint(constvector&);intmain(){vectorarray;array.push_back(1);array.push_back(6);array.push_back(6);array.push_back(3);//删除array数组中所有的6array.erase(remove(array.begin(),array.end(),6),array.end());print(array);return0;}voidprint(constvector&v){cout<<"nvectorsizeis:"<(cout,""));}#include#includeusingnamespacestd;intmain(){vectorarray;array.push_back(1);array.push_back(6);array.push_back(6);array.push_back(6);array.push_back(6);array.push_back(6);array.push_back(3);array.push_back(9);array.push_back(8);array.push_back(5);//ɾ³ýarrayÊý×éÖÐËùÓеÄ6vector::iteratoritor;itor=array.begin();for(itor=array.begin();itor!=array.end();++itor){if(6==itor){itor=array.erase(itor);--itor;}}cout<<"vectorsizeis:"<=1)年----当然,你没有把握的话,绝对不能乱说,社会上混,要讲信用的。有一次,我就在这个问题上吃了大亏,我看公司环境还不错,就我自做主张回答1年,结果,hr心目中是m(m>=2)年,呵呵,结果可想而知了。要知道,技术面试都过关了,Hr面试是2选1,在回家的路上,我只能祈祷对手自动放弃或找到了其他更好的工作。:)问第二个问题的是技术官。你要让他知道你已经做过哪些商业作品。一定要是商业作品。在里面负责哪方面具体工作,对于你熟悉的地方要多说。最好就是能争取笔试或上机,因为用用口说的话,大家理解都不一样,误差可能很大,结果对你相当不利。在这个问题上我也吃过亏的,曾有一个我很看好的职位,认为把握很大,业务理解上也很有优势,和技术官一谈,结果是gameover。要知道,在其他公司的上机和笔试中,我都能在应聘者中取得高分。再说我去面试别人的经验吧。当时,我的任务是出题,给分。若你觉得题很难,那么,请千万不要放弃,显然,你的对手也觉得难。只要坚持,我会认为这人有耐心很毅力,在以后的工作中也是好的合作者。题一定要做完,表现出认真的态度,若有疑问或卡壳,还可以寻求面试官的帮助,这些不会减分,相反,会增加你和他们的接触机会,面试官会评估你的沟通能力。有一次,有1个人来面试,题没有完全ok,但很规范,态度很认真,他把他知道的都做上去了,我给了他技术类的高分。后来,顺利进入公司,再后来进步很快,成了重要角色。若文章对你有帮助的话,请在此讨论。祝你成功面试题1.链表和数组的区别在哪里?2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法?4.请编写能直接实现strstr()函数功能的代码。5.编写反转字符串的程序,要求优化速度、优化空间。6.在链表里如何发现循环链接?7.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。8.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码,编写出一个从字符串到长整形的函数?)9.给出一个函数来输出一个字符串的所有排列。10.请编写实现malloc()内存分配函数功能一样的代码。11.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。12.怎样编写一个程序,把一个有序整数数组放到二叉树中?13.怎样从顶部开始逐层打印二叉树结点数据?请编程。14.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?另外:一、单项选择题:(共12题,每题2分,共24分)1.下面哪一个不是C++的标准数据类型?(D)A.intB.charC.boolD.real2.break关键字在哪一种语法结构中不能使用?(C)A.for语句B.switch语句C.if语句D.while语句3.类的继承方式有几种?(B)A.两种B.三种C.四种D.六种4.extern关键字的作用是什么?(D)A.声明外部链接B.声明外部头文件引用C.声明使用扩展C++语句D.声明外部成员函数、成员数据。5.C库函数strstr的功能是?(A)A.查找子串B.计算字符串长度C.字符串比较D.连结字符串6.stl::deque是一种什么数据类型?(A)A.动态数组B.链表C.堆栈D.树7.STL库里含有下面的哪一种泛型算法?(D)A.KMP查找B.折半查找C.冒泡排序D.快速排序8.现在最快且最通用的排序算法是什么?(A)A.快速排序B.冒泡排序C.选择排序D.外部排序9.Win32下的线程的哪一种优先级最高?(C)A.THREAD_PRIORITY_HIGHEST高优先级B.THREAD_PRIORITY_IDLE最低优先级,仅在系统空闲时执行C.THREAD_PRIORITY_TIME_CRITICAL最高优先级D.THREAD_PRIORITY_ABOVE_NORMAL高于普通优先级10.下面四个选项中,哪一个不是WinMain函数的参数?(D)A.HINSTANCEB.INTC.LPSTRD.WPARAM11.VC++的编译器中,运算符new底层的实现是什么?(B)A.VirtualAlloc()B.HeapAlloc()C.GlobalAlloc()D.AllocateUserPhysicalPages()12.下面哪一本C++参考书最厚?(C)A.《ThinkinC++》B.《深入浅出MFC》C.《C++Primer》D.《EffectiveC++》13.当调用WindowsAPI函数InvalidateRect,将会产生什么消息(A)A.WM_PAINTB.WM_CREATEC.WM_NCHITTESTD.WM_SETFOCUS14.关于virtualvoidDraw()=0,下面说法正确的有几个(C)(1)它是纯虚函数(对)(2)它在定义它的类中不能实现(对)(3)定义它的类不可实例化(对)(4)如果一个类要继承一个ADT类,必须要实现其中的所有纯虚函数(错)//可以不实现,派生之后的类仍旧作为一个抽象类.A.1B.2C.3D.4二、不定项选择题:(共6题,每题3分,共18分,多选、错选、漏选均不给分)1.vector::iterator重载了下面哪些运算符?(ACD)A.++B.>>C.(前置)D.==2.CreateFile()的功能有哪几个?(AB)A.打开文件B.创建新文件C.文件改名D.删除文件3.下面哪些是句柄(HANDLE)?(ABCD)A.HINSTANCE实例句柄B.HWND窗口句柄C.HDC设备描述符号句柄D.HFONT字体句柄4.下面哪些不是OpenGL标准几何元素的绘制模式?(A)A.GL_FOGB.GL_LINE_STRIPC.GL_POINTSD.GL_TRIANGLE_FAN5.下面哪些运算符不能被重载?(ABD)A.做用域运算符“::”B.对象成员运算符“.”C.指针成员运算符“->”D.三目运算符“?:”6.下面哪些人曾参与了世界上第一个C++编译器的开发?()A.BillGatesB.StanleyLippmanC.AndersonHejlsbergD.BjarneStroustrup7.以下说法正确的是?(ABC)A.头文件中的ifndef/define/endif是为了防止该头文件被重复引用。B.对于#include,编译器从标准库路径开始搜索filename.h对于#include“filename.h”,编译器从用户的工作路径开始搜索filename.hC.C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。D.fopen函数只是把文件目录信息调入内存。//错,fopen是把整个文件读入内存三、填空题:(共8题,每题3分,共24分)1.一个大小为320X192,颜色为灰度索引色的设备相关位图有______字节。如果此位图颜色为24位真彩色,则它的大小有______字节。2.WindowsAPI的中文意义是____windows应用程序接口___。3.计算反正弦的库函数是__asin()____;计算浮点数绝对值的库函数是__fabs()____;计算浮点数n次方的库函数是__pow()____;将浮点数转化为字符串的库函数是___fcvt()___。4.如果i等于5,那么(++i)--的返回值是__6__。5.APILoadBitmap()的功能是从__指定的模块和或应用程序实例__中读取位图数据到内存。6.new和__delete___对应,malloc和_free___对应,他们之间_不能__交叉混用。calloc的功能是__为数组动态分配内存___,realloc的功能是_改变原有内存区域的大小_。7.SendMessage和PostMessage都会向窗体发送一个消息,但SendMessage__将一条消息发送到指定窗口,立即处理__而PostMessage__将一条消息投递到指定窗口的消息队列,不需要立即处理___。8.输出指定圆心、半径、边数的圆上的点:constintnCount=12;constdoubledOrgX=5.0,dOrgY=3.0;constdoubledRadius=2.0;for(inti=0;i0;i--){for(intj=i-1;j>0;j--){System.out.print(i);System.out.print(j+"");}System.out.print("");}}}publicclassTest{publicstaticintgetDigits(Stringstr){int[]intarr=newint[10];for(inti=0;i<10;i++)intarr[i]=0;for(inti=0;i=10000)continue;if(fourth<100000fourth>=1000000)continue;Stringstr=String.valueOf(third)+String.valueOf(fourth);if(getDigits(str)==10)returnage;}return0;}}第二道题classCombine{publicstaticvoidmain(String[]args){for(inti=1;i<5;i++){for(intj=i+1;j<6;j++){System.out.println(i+""+j);System.out.println(j+""+i);}}}publicclassAge{publicstaticvoidmain(String[]args){Stringstr1=null;Stringstr2=null;Stringstr3=null;Stringstr4="0123456789";for(inti=10;i<50;i++){str1=Integer.toString(iii);str2=Integer.toString(iiii);str3=str1+str2;if((str1.length()==4)&&(str2.length()==6)){booleanflag=true;for(intj=0;j<10;j++)if(str3.indexOf(str4.charAt(j))==-1)flag=false;if(flag){System.out.println(">>>"+i);System.out.println(str3);}}}}}3、微软又一道笔试题怎样只用4行代码编写出一个从字符串到长整形的转换函数?我的方法,不过好象比4行多_#!~longatol(charstr){charc=str;if(!isdigit(c))str++;for(longvalue=0;str!=\'\';value=value10+(str-\'0\'),str++);returnc==\'-\'?-value:value;}voidstol(constchardes,long&num){for(intbase=1,i=0;des[i]!=\'\';base=10,++i){num=base;num+=(int)(des[i]-\'0\');}}num要初始化为0voidstol(constchardes,long&num){for(inti=num=0;des[i]!=\'\';i++){num=10;num+=(int)(des[i]-\'0\');}}voidstol(charstr,long&num){while(str!=\'\'){num=num10+(str-\'0\');str++;}}voidstol(constchardes,long&num){charp=des[0];for(intb=1,pos=1,base=1;des[pos]!=\'\';b=10,++pos,base=10){(num=b)+=(int)(des[pos]-\'0\');}p==\'-\'?(num=-1):(num=(int)(des[0]-\'0\')base+num);}改了一下真的是微软的笔试题么?我只用了一行。#includeusingnamespacestd;longstr2long(charp,longxxx=0L){returnp==\'\'?xxx:str2long(p,xxx10+(p+++0-\'0\'));}intmain(){charstr="123456789",p=str;cout<#include#includeusingnamespacestd;longToLong(string&s){longl;istringstreamiss(s);iss>>l;returnl;}intmain(intargc,_TCHARargv[]){strings="-12356";cout<usingnamespacestd;longstr2long(charp,longxxx=0L,boolIsPositive=true){returnp==\'\'?(IsPositive?xxx:xxx(-1)):(p==\'-\'?str2long(++p,0L,false):str2long(p,xxx10+p+++0-\'0\',IsPositive));}intmain(){charstr="-123456789",p=str;cout<6)puts(">6"):puts("<=6");}这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是“>6”。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。
13.评价下面的代码片断:unsignedintzero=0;unsignedintcompzero=0xFFFF;/1\'scomplementofzero对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下:unsignedintcompzero=~0;这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里,好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼。到了这个阶段,应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好,那么这个测试就在这里结束了。但如果显然应试者做得不错,那么我就扔出下面的追加问题,这些问题是比较难的,我想仅仅非常优秀的应试者能做得不错。提出这些问题,我希望更多看到应试者应付问题的方法,而不是答案。不管如何,你就当这个是娱乐吧…试题16:×××公司linux内核驱动研发招聘笔试题(一)主要题型:选择题(每题3分,约20题吧,具体什么题都有,包括网络、C连同其他硬件方面的基础知识);简答题(总分约40分,主要包括读C程式给出结果同时给出适当的解释及其他一些硬件方面的问题);(二)主要内容:1、题目概述(1)C方面:这一部分比较简单,主要是类似指针空间分配、strcpy(主要是考第一个参数是否有空间,结合指针空间分配考)、二重指针、++及――(先加后加,先减后减)等,更有就是volatile及register修饰符的意思。(2)其他方面:这一部分比较杂,什么都能够考您,多半都是基础知识,尤其是硬件方面,华为的主要题目为:(主要列出C以外的题目,我认为C是很简单的,^_^)2、具体题目(1)选择题部分:1、255.255.254.0网段最多能支持多少主机?(大概有5个备选项)2、10M网卡传输过程中物理层采用什么编码?(SNAP?)(大概有4个备选项)3、栈和队列的特点?(备选大概只有两个,A为FIFO,B为LIFO)4、Cache的工作方式划分?(大概也有4个答案,大概是:write-none,write-all,write-through,write-back)。5、什么叫NMI中断?(四个备选项)6、RISC主要性能及特性?(大概有6个备选项)7、在嵌入式系统中,所谓的北桥指的是什么?(2)简答题:1、说说轮巡任务调度和抢占式任务调度的区别?(大概为8分吧,记不清了)2、什么叫存储器高速缓存技术,其主要目的?(大概6分)3、画出电脑组成的最小逻辑框图。(哼,这道题竟然10分)4、谈谈Volatile和Register修饰符的作用?试题17:C++笔试题(1)一道C语言笔试题设一数据库人员档案表为如下结构:name(姓名)、address(地址)、Teleno(电话号码)、image(相片数据);存储长度:8Bytes、20Bytes、12Bytes、变长的二进制数据;若将数据库中的档案记录信息存入文件,其中相片数据信息数据可能或有或无,且即使有,数据信息亦不定长。问题:每一记录存储于文件时,其相片数据要求按它的实际长度来存放,试设计一数据结构,并解释各成员变量含义。一些C语言笔试题一、请填写BOOL,float,指针变量与“零值”比较的if语句。(10分)1.请写出BOOLflag与“零值”比较的if语句。(3分)标准答案:if(flag)if(!flag)如下写法均属不良风格,不得分。if(flag==TRUE)if(flag==1)if(flag==FALSE)if(flag==0)2.请写出floatx与“零值”比较的if语句。(4分)标准答案示例:constfloatEPSINON=0.000001;if((x<=-EPSINON)&&(x>=EPSINON)不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。如下是错误的写法,不得分。if(x==0.0)if(x!=0.0)3.请写出charp与“零值”比较的if语句。(3分)标准答案:if(p==NULL)if(p!=NULL)如下写法均属不良风格,不得分。if(p==0)if(p!=0)if(p)if(!)二、以下为WindowsNT下的32位C++程序,请计算sizeof的值(10分)charstr[]=“Hello”;charp=str;intn=10;1.请计算sizeof(str)=6(2分)//加上一个/0结束标志符共6位,且CHAR为一个字节sizeof(p)=4(2分)//指针变量的是四个字节sizeof(n)=4(2分)//int类型是四个字节voidFunc(charstr[100]){请计算sizeof(str)=4(2分)//void类型为四字节}voidp=malloc(100);请计算sizeof(p)=4(2分)//指针类型为四字节三、简答题(25分)1、头文件中的ifndef/define/endif干什么用?(5分)答:防止该头文件被重复引用。2、#include和#include“filename.h”有什么区别?(5分)答:对于#include,编译器从标准库路径开始搜索filename.h对于#include“filename.h”,编译器从用户的工作路径开始搜索filename.h3、const有什么用途?(请至少说明两种)(5分)答:(1)可以定义const常量(2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。4、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”?(5分)答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。5、请简述以下两个for循环的优缺点(5分)for(i=0;ii++){if(condition)DoSomething();elseDoOtherthing();}优点:程序简洁缺点:多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。if(condition){for(i=0;ii++)DoSomething();}else{for(i=0;ii++)DoOtherthing();}优点:循环的效率高缺点:程序不简洁四、有关内存的思考题(每小题5分,共20分)voidGetMemory(charp){p=(char)malloc(100);}voidTest(void){charstr=NULL;GetMemory(str);strcpy(str,"helloworld");printf(str);}请问运行Test函数会有什么样的结果?答:试题传入GetMemory(charp)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完charstr=NULL;GetMemory(str);后的str仍然为NULL;charGetMemory(void){charp[]="helloworld";returnp;}voidTest(void){charstr=NULL;str=GetMemory();printf(str);}请问运行Test函数会有什么样的结果?答:可能是乱码。charp[]="helloworld";returnp;的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。voidGetMemory2(charp,intnum){p=(char)malloc(num);}voidTest(void){charstr=NULL;GetMemory(&str,100);strcpy(str,"hello");printf(str);}请问运行Test函数会有什么样的结果?答:(1)能够输出hello(2)Test函数中也未对malloc的内存进行释放。(3)GetMemory避免了试题1的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句p=(char)malloc(num);后未判断内存是否申请成功,应加上:if(p==NULL){...//进行申请内存失败处理}voidTest(void){charstr=(char)malloc(100);strcpy(str,“hello”);free(str);if(str!=NULL){strcpy(str,“world”);printf(str);}}请问运行Test函数会有什么样的结果?答:执行charstr=(char)malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:str=NULL;五、编写strcpy函数(10分)已知strcpy函数的原型是charstrcpy(charstrDest,constcharstrSrc);其中strDest是目的字符串,strSrc是源字符串。(1)不调用C++/C的字符串库函数,请编写函数strcpycharstrcpy(charstrDest,constcharstrSrc);{assert((strDest!=NULL)&&(strSrc!=NULL));//2分charaddress=strDest;//2分while((strDest++=strSrc++)!=‘0’)//2分NULL;returnaddress;//2分}(2)strcpy能把strSrc的内容复制到strDest,为什么还要char类型的返回值?答:为了实现链式表达式。//2分例如intlength=strlen(strcpy(strDest,“helloworld”));六、编写类String的构造函数、析构函数和赋值函数(25分)已知类String的原型为:classString{public:String(constcharstr=NULL);//普通构造函数String(constString&other);//拷贝构造函数~String(void);//析构函数String&operate=(constString&other);//赋值函数private:charm_data;//用于保存字符串};请编写String的上述4个函数。标准答案://String的析构函数String::~String(void)//3分{delete[]m_data;//由于m_data是内部数据类型,也可以写成deletem_data;}//String的普通构造函数String::String(constcharstr)//6分{if(str==NULL){m_data=newchar[1];//若能加NULL判断则更好m_data=‘0’;}else{intlength=strlen(str);m_data=newchar[length+1];//若能加NULL判断则更好strcpy(m_data,str);}}//拷贝构造函数String::String(constString&other)//3分{intlength=strlen(other.m_data);m_data=newchar[length+1];//若能加NULL判断则更好strcpy(m_data,other.m_data);}//赋值函数String&String::operate=(constString&other)//13分{//(1)检查自赋值//4分if(this==&other)returnthis;//(2)释放原有的内存资源//3分delete[]m_data;//(3)分配新的内存资源,并复制内容//3分intlength=strlen(other.m_data);m_data=newchar[length+1];//若能加NULL判断则更好strcpy(m_data,other.m_data);//(4)返回本对象的引用//3分returnthis;}试题18:C/C++程序员应聘常见面试题深入剖析C/C++程序设计员应聘常见面试试题深入剖析本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。2.找错题试题1:以下是引用片段:voidtest1(){charstring[10];charstr1="0123456789";strcpy(string,str1);}试题2:以下是引用片段:voidtest2(){charstring[10],str1[10];inti;for(i=0;i<10;i++){str1=\'a\';}strcpy(string,str1);}试题3:以下是引用片段:voidtest3(charstr1){charstring[10];if(strlen(str1)<=10){strcpy(string,str1);}}解答:试题1字符串str1需要11个字节才能存放下(包括末尾的’\\0’),而string只有10个字节的空间,strcpy会导致数组越界;对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;对试题3,if(strlen(str1)<=10)应改为if(strlen(str1)<10),因为strlen的结果未统计’\\0’所占用的1个字节。剖析:考查对基本功的掌握:(1)字符串以’\\0’结尾;(2)对数组越界把握的敏感度;(3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:2分以下是引用片段:voidstrcpy(charstrDest,charstrSrc){while((strDest++=strSrc++)!=‘\\0’);}4分以下是引用片段:voidstrcpy(charstrDest,constcharstrSrc)//将源字符串加const,表明其为输入参数,加2分{while((strDest++=strSrc++)!=‘\\0’);}7分以下是引用片段:voidstrcpy(charstrDest,constcharstrSrc){//对源地址和目的地址加非0断言,加3分assert((strDest!=NULL)&&(strSrc!=NULL));while((strDest++=strSrc++)!=‘\\0’);}10分以下是引用片段://为了实现链式操作,将目的地址返回,加3分!charstrcpy(charstrDest,constcharstrSrc){assert((strDest!=NULL)&&(strSrc!=NULL));charaddress=strDest;while((strDest++=strSrc++)!=‘\\0’);returnaddress;}从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!(4)对strlen的掌握,它没有包括字符串末尾的\'\\0\'。读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:intstrlen(constcharstr)//输入参数const以下是引用片段:{assert(strt!=NULL);//断言字符串地址非0intlen;while((str++)!=\'\\0\'){len++;}returnlen;}试题4:以下是引用片段:voidGetMemory(charp){p=(char)malloc(100);}voidTest(void){charstr=NULL;GetMemory(str);strcpy(str,"helloworld");printf(str);}试题5:以下是引用片段:charGetMemory(void){charp[]="helloworld";returnp;}voidTest(void){charstr=NULL;str=GetMemory();printf(str);}试题6:以下是引用片段:voidGetMemory(charp,intnum){p=(char)malloc(num);}voidTest(void){charstr=NULL;GetMemory(&str,100);strcpy(str,"hello");printf(str);}试题7:以下是引用片段:voidTest(void){charstr=(char)malloc(100);strcpy(str,"hello");free(str);...//省略的其它语句}解答:试题4传入中GetMemory(charp)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完charstr=NULL;GetMemory(str);后的str仍然为NULL;试题5中charp[]="helloworld";returnp;的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句tiffanybraceletsp=(char)malloc(num);后未判断内存是否申请成功,应加上:if(p==NULL){...//进行申请内存失败处理}试题7存在与试题6同样的问题,在执行charstr=(char)malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:str=NULL;试题6的Test函数中也未对malloc的内存进行释放。剖析:试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。对内存操作的考查主要集中在:(1)指针的理解;(2)变量的生存期及作用范围;(3)良好的动态内存申请和释放习惯。再看看下面的一段程序有什么错误:以下是引用片段:swap(intp1,intp2){intp;p=p1;p1=p2;p2=p;}在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“AccessViolation”。该程序应该改为:以下是引用片段:swap(intp1,intp2){intp;p=p1;p1=p2;p2=p;}试题19:C/C++试题一、请填写BOOL,float,指针变量与“零值”比较的if语句。(10分)请写出BOOLflag与“零值”比较的if语句。(3分)标准答案:if(flag)if(!flag)如下写法均属不良风格,不得分。if(flag==TRUE)if(flag==1)if(flag==FALSE)if(flag==0)请写出floatx与“零值”比较的if语句。(4分)标准答案示例:constfloatEPSINON=0.00001;if((x>=-EPSINON)&&(x<=EPSINON)不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。如下是错误的写法,不得分。if(x==0.0)if(x!=0.0)请写出charp与“零值”比较的if语句。(3分)标准答案:if(p==NULL)if(p!=NULL)如下写法均属不良风格,不得分。if(p==0)if(p!=0)if(p)if(!)二、以下为WindowsNT下的32位C++程序,请计算sizeof的值(10分)charstr[]=“Hello”;charp=str;intn=10;请计算sizeof(str)=6(2分)sizeof(p)=4(2分)sizeof(n)=4(2分)voidFunc(charstr[100]){请计算sizeof(str)=4(2分)}voidp=malloc(100);请计算sizeof(p)=4(2分)三、简答题(25分)1、头文件中的ifndef/define/endif干什么用?(5分)答:防止该头文件被重复引用。2、#include
和#include“filename.h”有什么区别?(5分)答:对于#include,编译器从标准库路径开始搜索filename.h对于#include“filename.h”,编译器从用户的工作路径开始搜索filename.h3、const有什么用途?(请至少说明两种)(5分)答:(1)可以定义const常量(2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。4、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”?(5分)答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。5、请简述以下两个for循环的优缺点(5分)for(i=0;i(Y)?(Y)(X))//结尾没有;嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。while(1){}或者for(;;)4、关键字static的作用是什么?定义静态变量5、关键字const有什么含意?表示常量不可以修改的变量。6、关键字volatile有什么含意?并举出三个不同的例子?提示编译器对象的值可能在编译器未监测到的情况下改变。int(s[10])(int)表示的是什么啊int(s[10])(int)函数指针数组,每个指针指向一个intfunc(intparam)的函数。7.有以下表达式:inta=248;b=4;intconstc=21;constintd=&a;intconste=&b;intconstfconst=&a;请问下列表达式哪些会被编译器禁止?为什么?c=32;d=&b;d=43;e=34;e=&a;f=0x321f;c这是个什么东东,禁止d说了是const,禁止e=&a说了是const禁止constfconst=&a;禁止8.交换两个变量的值,不使用第三个变量。即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;9.c和c++中的struct有什么不同?c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private10.#include#includevoidgetmemory(charp){p=(char)malloc(100);strcpy(p,"helloworld");}intmain(){charstr=NULL;getmemory(&str);printf("%s/n",str);free(str);return0;}程序崩溃,getmemory中的malloc不能返回动态内存,free()对str操作很危险11.charszstr[10];strcpy(szstr,"0123456789");产生什么结果?为什么?长度不一样,会造成非法的OS12.列举几种进程的同步机制,并比较其优缺点。原子操作信号量机制自旋锁管程,会合,分布式系统13.进程之间通信的途径共享存储系统消息传递系统管道:以文件系统为基础14.进程死锁的原因资源竞争及进程推进顺序非法15.死锁的4个必要条件互斥、请求保持、不可剥夺、环路16.死锁的处理鸵鸟策略、预防策略、避免策略、检测与解除死锁17.操作系统中进程调度策略有哪几种?FCFS(先来先服务),优先级,时间片轮转,多级反馈18.类的静态成员和非静态成员有何区别?类的静态成员每个类只有一个,非静态成员每个对象一个19.纯虚函数如何定义?使用时应注意什么?virtualvoidf()=0;是接口,子类必须要实现20.数组和链表的区别数组:数据顺序存储,固定大小连表:数据可以随机存储,大小可动态改变22.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点?应用层表示层会话层运输层网络层物理链路层物理层tcp/udp属于运输层TCP服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。与TCP不同,UDP并不提供对IP协议的可靠机制、流控制以及错误恢复功能等。由于UDP比较简单,UDP头包含很少的字节,比TCP负载消耗少。tcp:提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好udp:不提供稳定的服务,包头小,开销小23:(void)ptr和((void))ptr的结果是否相同?其中ptr为同一个指针.(void)ptr和((void))ptr值是相同的24:intmain(){intx=3;printf("%d",x);return1;}问函数既然不会被其它函数调用,为什么要返回1?mainc标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息1,要对绝对地址0x100000赋值,我们可以用(unsignedint)0x100000=1234;那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?((void()())0x100000)();首先要将0x100000强制转换成函数指针,即:(void()())0x100000然后再调用它:((void()())0x100000)();用typedef可以看得更直观些:typedefvoid()()voidFuncPtr;((voidFuncPtr)0x100000)();25、已知一个数组table,用一个宏定义,求出数据的元素个数#defineNTBL(sizeof(table)/sizeof(table[0]))26、线程与进程的区别和联系?线程是否具有相同的堆栈?dll是否有独-立的堆栈?进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。每个线程有自己的堆栈。DLL中有没有独-立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调用,那么这个时候是不是说这个DLL没有自己独-立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独-立的堆栈?以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,很有可能导致程序崩溃。27、分析下面的程序unsignedshortA=10;printf("~A=%u\\n",~A);ucharc=128;printf("c=%d\\n",c);输出多少?并分析过程第一题,~A=0xfffffff5,int值为-11,但输出的是uint。所以输出4294967285第二题,c=0x80,输出的是int,最高位为1,是负数,所以它的值就是0x00的补码就是128,所以输出-128。这两道题都是在考察二进制向int或uint转换时的最高位处理。28、分析下面的程序:voidGetMemory(charp,intnum){p=(char)malloc(num);}intmain(){charstr=NULL;GetMemory(&str,100);strcpy(str,"hello");free(str);if(str!=NULL){strcpy(str,"world");}printf("\\nstris%s",str);getchar();}问输出结果是什么?输出strisworld。free只是释放的str指向的内存空间,它本身的值还是存在的.所以free之后,有一个好的习惯就是将str=NULL.此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出world来。这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的,只不过。。。。。。。。楼上都说过了,最好别这么干。试题21:linux面试题参考答案(选择题)二.单项选择题:1.下面的网络协议中,面向连接的的协议是:A。A传输控制协议B用户数据报协议C网际协议D网际控制报文协议2.在/etc/fstab文件中指定的文件系统加载参数中,D参数一般用于CD-ROM等移动设备。AdefaultsBswCrw和roDnoauto3.Linux文件权限一共10位长度,分成四段,第三段表示的内容是C。A文件类型B文件所有者的权限C文件所有者所在组的权限D其他用户的权限4.终止一个前台进程可能用到的命令和操作B。AkillB;+CCshutdownDhalt5.在使用mkdir命令创建新的目录时,在其父目录不存在时先创建父目录的选项是D。A-mB-dC-fD-p6.下面关于i节点描述错误的是A。Ai节点和文件是一一对应的Bi节点能描述文件占用的块数Ci节点描述了文件大小和指向数据块的指针D通过i节点实现文件的逻辑结构和物理结构的转换7.一个文件名字为rr.Z,可以用来解压缩的命令是:D。AtarBgzipCcompressDuncompress8.具有很多C语言的功能,又称过滤器的是C。AcshBtcshCawkDsed9.一台主机要实现通过局域网与另一个局域网通信,需要做的工作是C。A配置域名服务器B定义一条本机指向所在网络的路由C定义一条本机指向所在网络网关的路由D定义一条本机指向目标网络网关的路由10.建立动态路由需要用到的文件有D。A/etc/hostsB/etc/HOSTNAMEC/etc/resolv.confD/etc/gateways11.局域网的网络地址192.168.1.0/24,局域网络连接其它网络的网关地址是192.168.1.1。主机192.168.1.20访问172.16.1.0/24网络时,其路由设置正确的是B。Arouteadd–net192.168.1.0gw192.168.1.1netmask255.255.255.0metric1Brouteadd–net172.16.1.0gw192.168.1.1netmask255.255.255.255metric1Crouteadd–net172.16.1.0gw172.16.1.1netmask255.255.255.0metric1Drouteadddefault192.168.1.0netmask172.168.1.1metric112.下列提法中,不属于ifconfig命令作用范围的是D。A配置本地回环地址B配置网卡的IP地址C激活网络适配器D加载网卡到内核中13.下列关于链接描述,错误的是B。A硬链接就是让链接文件的i节点号指向被链接文件的i节点B硬链接和符号连接都是产生一个新的i节点C链接分为硬链接和符号链接D硬连接不能链接目录文件14.在局域网络内的某台主机用ping命令测试网络连接时发现网络内部的主机都可以连同,而不能与公网连通,问题可能是C。A主机IP设置有误B没有设置连接局域网的网关C局域网的网关或主机的网关设置有误D局域网DNS服务器设置有误15.下列文件中,包含了主机名到IP地址的映射关系的文件是:B。A/etc/HOSTNAMEB/etc/hostsC/etc/resolv.confD/etc/networks16.不需要编译内核的情况是D。A删除系统不用的设备驱动程序时B升级内核时C添加新硬件时D将网卡激活17.在shell中变量的赋值有四种方法,其中,采用name=12的方法称A。A直接赋值B使用read命令C使用命令行参数D使用命令的输出18.D命令可以从文本文件的每一行中截取指定内容的数据。AcpBddCfmtDcut19.下列不是Linux系统进程类型的是D。A交互进程B批处理进程C守护进程D就绪进程20.配置Apache1.3.19服务器需要修改的配置文件为___A______Ahttpd.confBaccess.confCsrm.confDnamed.conf21.内核不包括的子系统是D。A进程管理系统B内存管理系统CI/O管理系统D硬件管理系统22.在日常管理中,通常CPU会影响系统性能的情况是:A。ACPU已满负荷地运转BCPU的运行效率为30%CCPU的运行效率为50%DCPU的运行效率为80%23.若一台计算机的内存为128MB,则交换分区的大小通常是C。A64MBB128MBC256MBD512MB24.在安装Linux的过程中的第五步是让用户选择安装方式,如果用户希望安装部分组件(软件程序),并在选择好后让系统自动安装,应该选择的选项是D。AfullBexpertCnewbieDmenu25.Linux有三个查看文件的命令,若希望在查看文件内容过程中可以用光标上下移动来查看文件内容,应使用C命令。AcatBmoreClessDmenu26.下列信息是某系统用ps–ef命令列出的正在运行的进程,D进程是运行Internet超级服务器,它负责监听Internetsockets上的连接,并调用合适的服务器来处理接收的信息。Aroot14.00.0344204?S17:090:00initBroot20.00.129161520?S17:090:00/sbin/gettyCroot30.00.21364632?S17:090:00/usr/sbin/syslogdDroot40.013441204?S17:090:10/usr/sbin/inetd27.在TCP/IP模型中,应用层包含了所有的高层协议,在下列的一些应用协议中,B是能够实现本地与远程主机之间的文件传输工作。AtelnetBFTPCSNMPDNFS28.当我们与某远程网络连接不上时,就需要跟踪路由查看,以便了解在网络的什么位置出现了问题,满足该目的的命令是C。ApingBifconfigCtracerouteDnetstat29.对名为fido的文件用chmod551fido进行了修改,则它的许可权是D。A-rwxr-xr-xB-rwxr--r--C-r--r--r--D-r-xr-x—x30.在i节点表中的磁盘地址表中,若一个文件的长度是从磁盘地址表的第1块到第11块,则该文件共占有B块号。A256B266C11D256×1031.用ls–al命令列出下面的文件列表,D文件是符号连接文件。A-rw-rw-rw-2hel-susers56Sep0911:05helloB-rwxrwxrwx2hel-susers56Sep0911:05goodbeyCdrwxr--r--1helusers1024Sep1008:10zhangDlrwxr--r--1helusers2024Sep1208:12cheng32.DNS域名系统主要负责主机名和A之间的解析。AIP地址BMAC地址C网络地址D主机别名33.WWW服务器是在Internet上使用最为广泛,它采用的是B结构。A服务器/工作站BB/SC集中式D分布式34.Linux系统通过C命令给其他用户发消息。AlessBmesgyCwriteDechoto35.NFS是C系统。A文件B磁盘C网络文件D操作36.B命令可以在Linux的安全系统中完成文件向磁带备份的工作。AcpBtrCdirDcpio37.Linux文件系统的文件都按其作用分门别类地放在相关的目录中,对于外部设备文件,一般应将其放在C目录中。A/binB/etcC/devD/lib38.在重新启动Linux系统的同时把内存中的信息写入硬盘,应使用D命令实现。A#rebootB#haltC#rebootD#shutdown–rnow39.网络管理具备以下几大功能:配置管理、A、性能管理、安全管理和计费管理等。A故障管理B日常备份管理C升级管理D发送邮件40.关于代理服务器的论述,正确的是A。A使用internet上已有的公开代理服务器,只需配置客户端。B代理服务器只能代理客户端http的请求。C设置好的代理服务器可以被网络上任何主机使用。D使用代理服务器的客户端没有自己的ip地址。试题22:1、请说出static和const关键字尽可能多的作用解答:static关键字至少有下列n个作用:(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。const关键字至少有下列n个作用:(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:constclassAoperator(constclassA&a1,constclassA&a2);operator的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:classAa,b,c;(ab)=c;//对ab的结果赋值操作(ab)=c显然不符合编程者的初衷,也没有任何意义。2.技巧题试题1:请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1解答:intcheckCPU(){{unionw{inta;charb;}c;c.a=1;return(c.b==1);}}剖析:嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地址存放内容0x40000x340x40010x12而在Big-endian模式CPU内存中的存放方式则为:内存地址存放内容0x40000x120x40010x3432bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地址存放内容0x40000x780x40010x560x40020x340x40030x12而在Big-endian模式CPU内存中的存放方式则为:内存地址存放内容0x40000x120x40010x340x40020x560x40030x78联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。试题2:写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)解答:intSum(intn){return((long)1+n)n/2;//或return(1l+n)n/2;}剖析:对于这个题,只能说,也许最简单的答案就是最好的答案。下面的解答,或者基于下面的解答思路去优化,不管怎么“折腾”,其效率也不可能与直接return(1l+n)n/2相比!intSum(intn){longsum=0;for(inti=1;i<=n;i++){sum+=i;}returnsum;}试题23:考查嵌入式C开发人员的最好的0x10道题第1题:考查对volatile关键字的认识#includestaticjmp_bufbuf;main(){volatileintb;b=3;if(setjmp(buf)!=0){printf("%d",b);exit(0);}b=5;longjmp(buf,1);}请问,这段程序的输出是(a)3(b)5(c)0(d)以上均不是第1题:(b)volatile字面意思是易于挥发的。这个关键字来描述一个变量时,意味着给该变量赋值(写入)之后,马上再读取,写入的值与读取的值可能不一样,所以说它"容易挥发"的。这是因为这个变量可能一个寄存器,直接与外部设备相连,你写入之后,该寄存器也有可能被外部设备的写操作所改变;或者,该变量被一个中断程序,或另一个进程改变了.volatile不会被编译器优化影响,在longjump后,它的值是后面假定的变量值,b最后的值是5,所以5被打印出来.setjmp:设置非局部跳转/setjmp.h/Storescontextinformationsuchasregistervaluessothatthelomgjmpfunctioncanreturncontroltothestatementfollowingtheonecallingsetjmp.Returns0whenitisinitiallycalled.Lonjjmp:执行一个非局部跳转/setjmp.h/Transferscontroltothestatementwherethecalltosetjmp(whichinitializedbuf)wasmade.Executioncontinuesatthispointasiflongjmpcannotreturnthevalue0.Anonvolatileautomaticvariablemightbechangedbyacalltolongjmp.Whenyouusesetjmpandlongjmp,theonlyautomaticvariablesguaranteedtoremainvalidarethosedeclaredvolatile.Note:Testprogramwithoutvolatilequalifier(resultmayvery)第2题:考查类型转换main(){structnode{inta;intb;intc;};structnodes={3,5,6};structnodept=&s;printf("%d",(int)pt);}这段程序的输出是:(a)3(b)5(c)6(d)7第2题:(a)结构题的成员在内存中的地址是按照他们定义的位置顺序依次增长的。如果一个结构体的指针被看成它的第一个成员的指针,那么该指针的确指向第一个成员第3题:考查递归调用intfoo(intx,intn){intval;val=1;if(n>0){if(n%2==1)val=valx;val=valfoo(xx,n/2);}returnval;}这段代码对x和n完成什么样的功能(操作)?(a)x^n(x的n次幂)(b)xn(x与n的乘积)(c)n^x(n的x次幂)(d)以上均不是第3题:(a)此题目较难.这个程序的非递归版本intwhat(intx,intn){intval;intproduct;product=1;val=x;while(n>0){if(n%2==1)product=productval;/如果是奇数次幂,x(val)要先乘上一次,;偶数次幂,最后返回时才会到这里乘以1/val=valval;n=n/2;}returnproduct;}/用二元复乘策略算法描述(whilen>0){ifnextmostsignificantbinarydigitofn(power)isonethenmultiplyaccumulatedproductbycurrentval,reducen(power)sequencebyafactoroftwousingintegerdivision.getnextvalbymultiplycurrentvalueofitself}第4题:考查指针,这道题只适合于那些特别细心且对指针和数组有深入理解的人main(){inta[5]={1,2,3,4,5};intptr=(int)(&a+1);printf("%d%d",(a+1),(ptr-1));}这段程序的输出是:(a)22(b)21(c)25(d)以上均不是第4题:(c)a的类型是一个整型数组,它有5个成员&a的类型是一个整型数组的指针所以&a+1指向的地方等同于a[6]所以(a+1)等同于a[1]ptr等同a[6],ptr-1就等同与a[5]第5题:考查多维数组与指针voidfoo(int[][3]);main(){inta[3][3]={{1,2,3},{4,5,6},{7,8,9}};foo(a);printf("%d",a[2][1]);}voidfoo(intb[][3]){++b;b[1][1]=9;}这段程序的输出是:(a)8(b)9(c)7(d)以上均不对第5题:(b)题目自身就给了足够的提示b[0][0]=4b[1][0]=7第6题目:考查逗号表达式main(){inta,b,c,d;a=3;b=5;c=a,b;d=(a,b);printf("c=%d",c);printf("d=%d",d);}这段程序的输出是:(a)c=3d=3(b)c=5d=3(c)c=3d=5(d)c=5d=5第6题:(c)考查逗号表达式,逗号表达式的优先级是很低的,比赋值(=)的优先级低.逗号表达式的值就是最后一个元素的值逗号表达式的还有一个作用就是分割函数的参数列表..E1,E2,...,En上面这个表示式的左右是,E1,E2,...En的值被分别计算出来,En计算出来的结构赋给整个逗号表达式c=a,b;/yieldsc=a/d=(a,b);/d=b第7题:考查指针数组main(){inta[][3]={1,2,3,4,5,6};int(ptr)[3]=a;printf("%d%d",(ptr)[1],(ptr)[2]);++ptr;printf("%d%d",(ptr)[1],(ptr)[2]);}这段程序的输出是:(a)2356(b)2345(c)4500(d)以上均不对第7题:(a)ptr是一个数组的指针,该数组有3个int成员第8题:考查函数指针intf1(void){intx=10;return(&x);}intf2(void){intptr;ptr=10;returnptr;}intf3(void){intptr;ptr=(int)malloc(sizeof(int));returnptr;}上面这3个函数哪一个最可能引起指针方面的问题(a)只有f3(b)只有f1andf3(c)只有f1andf2(d)f1,f2,f3第8题:(c)f1显然有问题,它返回一个局部变量的指针,局部变量是保存在stack中的,退出函数后,局部变量就销毁了,保留其指针没有意义,因为其指向的stack空间可能被其他变量覆盖了f2也有问题,ptr是局部变量,未初始化,它的值是未知的,ptr不知道指向哪里了,直接给ptr赋值可能会覆盖重要的系统变量,这就是通常说的野指针的一种第9题:考查自加操作(++)main(){inti=3;intj;j=sizeof(++i+++i);printf("i=%dj=%d",i,j);}这段程序的输出是:(a)i=4j=2(b)i=3j=2(c)i=3j=4(d)i=3j=6第9题:(b)sizeof操作符给出其操作数需要占用的空间大小,它是在编译时就可确定的,所以其操作数即使是一个表达式,也不需要在运行时进行计算.(++i+++i)是不会执行的,所以i的值还是3第10题:考查形式参数,实际参数,指针和数组voidf1(int,int);voidf2(int,int);void(p[2])(int,int);main(){inta;intb;p[0]=f1;p[1]=f2;a=3;b=5;p[0](&a,b);printf("%d\\t%d\\t",a,b);p[1](&a,b);printf("%d\\t%d\\t",a,b);}voidf1(intp,intq){inttmp;tmp=p;p=q;q=tmp;}voidf2(intp,intq){inttmp;tmp=p;p=q;q=tmp;}这段程序的输出是:(a)5555(b)3535(c)5353(d)3333第10题:(a)很显然选a.f1交换p和q的值,f1执行完后,p和q的值的确交换了,但q的改变不会影响到b的改变,p实际上就是a所以执行f1后,a=b=5这道题考查的知识范围很广,包括typedef自定义类型,函数指针,指针数组void(p[2])(int,int);定义了一个函数指针的数组p,p有两个指针元素.元素是函数的指针,函数指针指向的函数是一个带2个参数,返回void的函数,所带的两个参数是指向整型的指针,和整型p[0]=f1;p[1]=f2containaddressoffunction.functionnamewithoutparenthesisrepresentaddressoffunctionValueandaddressofvariableispassedtofunctiononlyargumentthatiseffectedisa(addressispassed).Becauseofcallbyvaluef1,f2cannoteffectb第11题:考查自减操作(--)voide(int);main(){inta;a=3;e(a);}voide(intn){if(n>0){e(--n);printf("%d",n);e(--n);}}这段程序的输出是:(a)0120(b)0121(c)1201(d)0211第11题:(a)考查--操作和递归调用,仔细分析一下就可以了第12题:考查typedef类型定义,函数指针typedefint(test)(float,float)testtmp;tmp的类型是(a)函数的指针,该函数以两个指向浮点数(float)的指针(pointer)作为参数(arguments)Pointertofunctionofhavingtwoargumentsthatispointertofloat(b)整型(c)函数的指针,该函数以两个指向浮点数(float)的指针(pointer)作为参数(arguments),并且函数的返回值类型是整型Pointertofunctionhavingtwoargumentthatispointertofloatandreturnint(d)以上都不是第12题:(c)分析函数声明,建议不会的看看《C专家编程》这里介绍一个简单规则:从左往有,遇到括号停下来,将第一个括号里的东西看成一个整体第13题:数组与指针的区别与联系main(){charp;charbuf[10]={1,2,3,4,5,6,9,8};p=(buf+1)[5];printf("%d",p);}这段程序的输出是:(a)5(b)6(c)9(d)以上都不对第13题:(c)考查什么时候数组就是指针.对某些类型T而言,如果一个表达式是T[](T的数组),这个表达式的值实际上就是指向该数组的第一个元素的指针.所以(buf+1)[5]实际上就是(buf+6)或者buf[6]第14题:考查指针数组的指针Voidf(char);main(){charargv[]={"ab","cd","ef","gh","ij","kl"};f(argv);}voidf(charp){chart;t=(p+=sizeof(int))[-1];printf("%s",t);}这段程序的输出是:(a)ab(b)cd(c)ef(d)gh第14题:(b)sizeof(int)的值是2,所以p+=sizeof(int)指向argv[2],这点估计大家都没有什么疑问(p+=sizeof(int))[-1]指向argv[1],能理解吗,因为(p+=sizeof(int))[-1]就相当于(p+=2)[-1],也就是(p+2-1)第15题:此题考查的是C的变长参数,就像标准函数库里printf()那样,这个话题一般国内大学课堂是不会讲到的,不会也情有可原呵呵,#includeintripple(int,...);main(){intnum;num=ripple(3,5,7);printf("%d",num);}intripple(intn,...){inti,j;intk;va_listp;k=0;j=1;va_start(p,n);for(;jintmain(void){chara[]="hello";intb[]={1,2,3,4,5};printf("a:%d\\n",sizeof(a));printf("bmemorysize:%dbytes\\n",sizeof(b));printf("belements:%d\\n",sizeof(b)/sizeof(int));return0;}数组a为字符型,后面的字符串实际上占据6个字节空间(注意最后有一个\\0标识字符串的结束)。从后面sizeof(b)就可以看出如何获得数组占据的内存空间,如何获得数组的元素数目。至于int数据类型分配内存空间的多少,则是编译器相关的。gcc默认为int类型分配4个字节的内存空间。(2)空间的分配这里又分为两种情况。第一,如果是全局的和静态的charp=“hello”;这是定义了一个指针,指向rodatasection里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。chara[]=“hello”;这是定义了一个数组,分配在可写数据块,不会被放到字符串池。第二,如果是局部的charp=“hello”;这是定义了一个指针,指向rodatasection里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。另外,在函数中可以返回它的地址,也就是说,指针是局部变量,但是它指向的内容是全局的。chara[]=“hello”;这是定义了一个数组,分配在堆栈上,初始化由编译器进行。(短的时候直接用指令填充,长的时候就从全局字符串表拷贝),不会被放到字符串池(同样如前,可能会从字符串池中拷贝过来)。注意不应该返回它的地址。(3)使用方法如果是全局指针,用于不需要修改内容,但是可能会修改指针的情况。如果是全局数组,用于不需要修改地址,但是却需要修改内容的情况。如果既需要修改指针,又需要修改内容,那么就定义一个数组,再定义一个指针指向它就可以了。2我编写的修改方案[armlinux@lqmpointer]$catpointer.c/Copyright2007(c),ShandongUniversityAllrightsreserved.Filename:test.cDescription:aboutpointerAuthor:LiuQingminVersion:1.0Date:2007-08-27#include/defineamacrowhichisusedtodebugarraymodeandpointermode.if1,debugarraymode;elsedebugpointermode.Youcanchangeitaccordingtoyourdecision.#defineARRAY_OR_POINTER0intmain(void){charp1;charp2;charpp;//test1#ifARRAY_OR_POINTERcharch[]="hello,world!\\n";printf("%d,%d,%d,%d\\n",sizeof(p1),sizeof(p2),sizeof(pp),sizeof(ch));#elsecharch="hello,world!\\n";printf("%d,%d,%d,%d\\n",sizeof(p1),sizeof(p2),sizeof(pp),sizeof(ch));#endif//test2p1=ch;#ifARRAY_OR_POINTERpp=&p1;#elsepp=&ch;#endifp2=pp;if(p1==p2){printf("p1equalstop2\\n");}else{printf("p1doesn\'tequaltop2\\n");}return0;}执行结果如下://ARRAY_OR_POINTER为0时[armlinux@lqmpointer]$./test4,4,4,4p1equalstop2//ARRAY_OR_POINTER为1时[armlinux@lqmpointer]$./test4,4,4,15p1equalstop2如果使用了数组定义方式,而又使用pp=&ch,那么就会出现类似下面的错误:[armlinux@lqmpointer]$makegcc-Wall-g-O2-c-opointer.opointer.cpointer.c:Infunction`main\':pointer.c:44:warning:assignmentfromincompatiblepointertypegcc-Wall-g-O2pointer.o-otest[armlinux@lqmpointer]$./test4,4,4,15p1doesn\'tequaltop2试题25:嵌入式研发工程师面试试题大全(ANSICC++方面的知识)一.ANSIC/C++方面的知识1、简答题。1、如何在C中初始化一个字符数组。逐个字符赋值:chars[]={‘A’,’B’,’C’,’D’};字符串赋值:chars[]={“ABCD”};对于二维字符数组:chars[2][10]={“cheng”,”jinzhou”};2、如何在C中为一个数组分配空间。如果是栈的形式,Types[N]定义后系统自动分配空间,分配的空间大小受操作系统限制;若是堆的形式,Types;s=(Type)malloc(sizeof(Type)N);分配的空间大小不受操作系统限制。3、如何初始化一个指针数组。这里有必要重新对比一下指针数组与数组指针的差异。a.指针数组:数组里存储的是指针。如:ints[5]表示数组s里存储了5个指向整型的指针。Chars[3]={“aaaaa”,”bbb”,”ccccc”}表示数组s里存储3个指向字符型的指针,分别指向字符串aaaaa、bbb、ccccc。b.数组指针:其实就是数组,里面存放的是数据。如:int(s)[5]表示数组s里存储了5个整型数据。4、如何定义一个有10个元素的整数型指针数组。Ints[10];5、s[10]的另外一种表达方式是什么。(s+10)二维数组S[5][8]的表示方法:((s+5)+8)7、要使用CHAR_BIT需要包含哪个头文件。Includelimits.h在该头文件里#defineCHAR_BIT88、对(-1.2345)取整是多少?-19、如何让局部变量具有全局生命期。使用Static,局部变量就存储在全局区(静态区),便具有全局的生命期和局部的访问控制。10、C中的常量字符串应在何时定义?没有理解到题目的意思,我只是想说明一点,定义常量字符串后它属于const型,不能去修改它,否则程序出错。11、如何在两个.c文件中引用对方的变量。尚不清楚,望博友能告知,万分感谢!12、使用malloc之前需要做什么准备工作。定义一个指针后就可以malloc了。13、realloc函数在使用上要注意什么问题。Realloc后返回的指针与之前malloc返回的指针指向的地址不同。14、strtok函数在使用上要注意什么问题。首次调用时,s必须指向要分解的字符串,随后调用要把s设成NULL15、gets函数在使用上要注意什么问题。这里要将Scanf()、gets()放在一起比较。Scanf()是遇到空格就判断为输入结束,而gets()则遇到回车才判断为输入结束。16、C语言的词法分析在长度规则方面采用的是什么策略?尚不清楚,望博友能告知,万分感谢!17、a+++++b所表示的是什么意思?有什么问题?根据自增运算符的右结合性,它是(a++)+(++b)的意思,但有的编译器里省略括号就不能通过,同时也降低了程序可读性。18、如何定义Bool变量的TRUE和FALSE的值。#defineTRUE1#defineFALSE019、C语言的const的含义是什么。在定义常量时,为什么推荐使用const,而不是#define。Const是只读的意思,它限定一个变量不允许被改变。#define缺乏类型检测机制,在预处理时候有可能引发错误。Const方面的其它知识扩展:问题1:const变量&const限定的内容下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢?typedefcharpStr;charstring[4]="abc";constcharp1=string;//p1作为整体不能被修改,但p1可以修改,p1++合法constpStrp2=string;//p2作为一个整体,不能被修改,但是下面的p2++非法修改p1++;p2++;问题2:const变量&字符串常量请问下面的代码有什么问题?charp="i\'\'\'\'mhungry!";//定义的是字符串常量p[0]=\'\'\'\'I\'\'//不能修改字符串常量问题:const变量&字符串常量2chara[3]="abc"合法吗?使用它有什么隐患?没有考虑到字符串结束符‘\\0’,所以会产生意想不到的错误。比如以下程序:intmain(){inti;charp[6]={\'\'\'\'a\'\'\'\',\'\'\'\'b\'\'\'\',\'\'\'\'c\'\'\'\',\'\'\'\'d\'\'\'\',\'\'\'\'e\'\'\'\',\'\'\'\'f\'\'\'\'};printf("%s",p);while(1);return0;}运行后显示:abcdef@问题3:const&指针类型声明中const用来修饰一个常量,有如下两种写法,那么,请问,下面分别用const限定不可变的内容是什么?1)、const在前面a.constintnValue;//nValue是const把类型int撇开,变量nValue作为一个整体,因此nValue是const型;b.constcharpContent;//pContent是const,pContent可变把类型char撇开,变量pContent作为一个整体,因此pContent是const型;c.const(char)pContent;//pContent是const,pContent可变把类型char撇开,注意这里(char)是一个整体,而变量pContent作为一个整体,因此pContent是const型;d.charconstpContent;//pContent是const,pContent可变const与变量间没有类型,变量pContent作为一个整体,因此pContent是const型;e.constcharconstpContent;//pContent和pContent都是const这里分为两层,外层:把类型char撇开,变量constpContent作为一个整体,因此pContent是const型;内层:没有类型,因此pContent是const型。2)、const在后面,与上面的声明对等(这类型更容易判断)a.intconstnValue;//nValue是constconst与变量之间没有类型,const后面那部分整体是const型,因此nValue是const型b.charconstpContent;//pContent是const,pContent可变const与变量之间没有类型,const后面那部分整体是const型,因此pContent是const型c.(char)constpContent;//pContent是const,pContent可变const与变量之间没有类型,const后面那部分整体是const型,因此pContent是const型d.charconstpContent;//pContent是const,pContent可变const与变量之间没有类型,const后面那部分整体是const型,因此pContent是const型e.charconstconstpContent;//pContent和pContent都是const分为两层,外层:撇开类型char,const后面那部分整体constpContent是const型,因此pContent是const型;内层:const与pContent之间无类型,因此pContent是const型。C++中CONSTC中常用:#define变量名变量值定义一个值替代,然而却有个致命缺点:缺乏类型检测机制,这样预处理理在C++中成为可能引发错误的隐患,于是引入const.const使用:1.用于指针的两种情况:const是一个左结合的类型修饰符.intconstA;//A可变,A不可变intconstA;//A不可变,A可变2.限定函数的传递值参数:voidfunction(constintVar);//传递过来的参数在函数内不可以改变.3.限定函数返回值型.constintfunction();//此时const无意义constmyclassnamefunction();//函数返回自定义类型myclassname.20、C语言的volatile的含义是什么。使用时会对编译器有什么暗示。volatile的本意是“易变的”由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化,但有可能会读脏数据。当要求使用volatile声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:1).并行设备的硬件寄存器(如:状态寄存器)2).一个中断服务子程序中会访问到的非自动变量(Non-automaticvariables)3).多线程应用中被几个任务共享的变量嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。Volatile的完全扩展:1).一个参数既可以是const还可以是volatile吗?解释为什么。是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。2).一个指针可以是volatile吗?解释为什么。是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。3).下面的函数有什么错误:intsquare(volatileintptr){returnptrptr;}这段代码的有个恶作剧。这段代码的目的是用来返指针ptr指向值的平方,但是,由于ptr指向一个volatile型参数,编译器将产生类似下面的代码:intsquare(volatileintptr){inta,b;a=ptr;b=ptr;returnab;}由于ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:longsquare(volatileintptr){inta;a=ptr;returnaa;}试题26:华为面试题1、请你分别划划OSI的七层网络结构图和TCP/IP的五层结构图2、请你详细的解释一下IP协议的定义在哪个层上面主要有什么作用TCP与UDP呢3、请问交换机和路由器分别的实现原理是什么分别在哪个层次上面实现的4、请问C++的类和C里面的struct有什么区别5、请讲一讲析构函数和虚函数的用法和作用6、全局变量和局部变量有什么区别实怎么实现的操作系统和编译器是怎么知道的7、一些寄存器的题目主要是寻址和内存管理等一些知识8、8086是多少位的系统在数据总线上是怎么实现的试题27:Intel的笔试题1.三个float:a,b,c问值(a+b)+c==(b+a)+c(a+b)+c==(a+c)+b2.把一个链表反向填空3.设计一个重采样系统说明如何anti-alias4.y1(n)=x(2n),y2(n)=x(n/2),问如果y1为周期函数那么x是否为周期函数如果x为周期函数那么y1是否为周期函数如果y2为周期函数那么x是否为周期函数如果x为周期函数那么y2是否为周期函数5.如果模拟信号的带宽为5KHZ要用8K的采样率怎么办6.某个程序在一个嵌入式系统(200M的CPU,50M的SDRAM)中已经最化了换到另一个系统(300M的CPU,50M的SDRAM)中运行还需要优化吗7.x^4+ax^3+x^2+cx+d最少需要作几次乘法8.什么情况下sin(x+y)+y~....9.下面哪种排序法对12354最快:Baquicksortb.bublesortc.mergesort10.哪种结构平均来讲获取一个值最快:Ba.binarytreeb.hashtablec.stack2008-12-31更新:1、编译成功后的信息第一行,code,R0data,RWdata,ZIdata分别代表什么?答案:R0只读段,即程序代码空间;RW可读/写段,即数据变量空间;ZI清零变量段,即需要清零初始化的数据变量空间.2、下列对重载函数的描述中,(A)是错误的。A)重载函数中不允许使用默认参数B)重载函数中编译时根据参数表进行选择C)不要使用重载函数来描述毫无相干的函数D)构造函数重载将会给初始化带来多种方式3、描述一下嵌入式基于ROM的运行方式与基于ram的运行方式有什么区别。rom运行方式是指指令从rom中取出,首先对rom有一定要求(例如按block进行读写,nandflash就不支持rom运行,同时由于rom读写的限制,无法完成异常处理,即异常处理函数肯定放在ram中)。在有区别就是片选不一样。12.1第20页,试题9',)