《程序员笔试面试2578.docx》由会员分享,可在线阅读,更多相关《程序员笔试面试2578.docx(77页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、先发基本问问题,再发发编程问题题.想成为嵌入入式程序员员应知道的的0x100个基本问问题:1:(vooid *)ptrr 和 (*(vooid*)pttr的结果果是否相同同?其中pptr为同同一个指针针.(voiid *)ptr 和 (*(voiid*)ptrr值是相同同的2:intt maiin() iint xx=3; pprinttf(%d,xx); rreturrn 1; 问函数既然然不会被其其它函数调调用,为什什么要返回回 1?mian中中,c标准准认为0表表示成功,非非0表示错错误。具体体的值是某某中具体出出错信息1,要对绝绝对地址00x1000000赋赋值,我们们可以用(unsi
2、ignedd intt*)0xx1000000 = 12334;那么要是想想让程序跳跳转到绝对对地址是00x1000000去去执行,应应该怎么做做?*(vooid (*)( )0xx1000000 ) ( );首先要将00x1000000强强制转换成成函数指针针,即:(voidd (*)()00x1000000然后再调用用它:*(vooid (*)()0x11000000)();用typeedef可可以看得更更直观些:typeddef vvoid(*)() voiidFunncPtrr;*(vooidFuuncPttr)0xx1000000)();2,已知一一个数组ttablee,用一个个宏定
3、义,求求出数据的的元素个数数#defiine NNTBL#defiine NNTBL (sizzeof(tablle)/ssizeoof(taable0)面试题: 线程与进进程的区别别和联系? 线程是是否具有相相同的堆栈栈? dlll是否有有独立的堆堆栈?进程是死的的,只是一一些资源的的集合,真真正的程序序执行都是是线程来完完成的,程程序启动的的时候操作作系统就帮帮你创建了了一个主线线程。每个线程有有自己的堆堆栈。DLL中有有没有独立立的堆栈,这这个问题不不好回答,或或者说这个个问题本身身是否有问问题。因为为DLL中中的代码是是被某些线线程所执行行,只有线线程拥有堆堆栈,如果果DLL中中的代码
4、是是EXE中中的线程所所调用,那那么这个时时候是不是是说这个DDLL没有有自己独立立的堆栈?如果DLLL中的代代码是由DDLL自己己创建的线线程所执行行,那么是是不是说DDLL有独独立的堆栈栈?以上讲的是是堆栈,如如果对于堆堆来说,每每个DLLL有自己的的堆,所以以如果是从从DLL中中动态分配配的内存,最最好是从DDLL中删删除,如果果你从DLLL中分配配内存,然然后在EXXE中,或或者另外一一个DLLL中删除,很很有可能导导致程序崩崩溃unsiggned shorrt A = 100;printtf(A = %unn, A);char c=1228; printtf(cc=%dn,cc);输
5、出多少?并分析过过程第一题,A 00xfffffffff5,innt值 为为11,但但输出的是是uintt。所以输输出429949677285第二题,cc0x110,输出出的是innt,最高高位为1,是是负数,所所以它的值值就是0xx00的补补码就是1128,所所以输出128。这两道题都都是在考察察二进制向向int或或uintt转换时的的最高位处处理。分析下面的的程序:void GetMMemorry(chhar *p,iint nnum) *p=(cchar *)maallocc(numm); int mmain() cchar *strr=NULLL; GGetMeemoryy(&sttr
6、,1000); sstrcppy(sttr,hhelloo); ffree(str); iif(sttr!=NNULL) sstrcppy(sttr,wworldd); pprinttf(n sttr iss %s,strr); ggetchhar(); 问输出结果果是什么?希望大家家能说说原原因,先谢谢谢了输出strr is worlld。free 只是释放放的strr指向的内内存空间,它本身的的值还是存存在的.所以freee之后,有有一个好的的习惯就是是将strr=NULLL.此时strr指向空间间的内存已已被回收,如果输出出语句之前前还存在分分配空间的的操作的话话,这段存存储空间是是可能
7、被重重新分配给给其他变量量的,尽管这段程程序确实是是存在大大大的问题(上上面各位已已经说得很很清楚了),但但是通常会会打印出wworldd来。这是因为,进进程中的内内存管理一一般不是由由操作系统统完成的,而而是由库函函数自己完完成的。当你mallloc一一块内存的的时候,管管理库向操操作系统申申请一块空空间(可能能会比你申申请的大一一些),然然后在这块块空间中记记录一些管管理信息(一一般是在你你申请的内内存前面一一点),并并将可用内内存的地址址返回。但但是释放内内存的时候候,管理库库通常都不不会将内存存还给操作作系统,因因此你是可可以继续访访问这块地地址的,只只不过。楼楼上都说过过了,最好好别
8、这么干干。char a100,sttrlenn(a)为为什么等于于一五?运运行的结果果#incllude stddio.hh#incllude strring.hvoid mainn()char aa110;printtf(%d,sstrleen(aaa);sizeoof()和和初不初始始化,没有有关系;strleen()和和初始化有有关。char (*sttr)220;/*strr是一个数数组指针,即即指向数组组的指针*/char *strr20;/*sstr是一一个指针数数组,其元元素为指针针型数据*/long a=0xx8010010;a+5=?0x8011010用用二进制表表示为:“1
9、0000 00000 00001 00000 00011 00000”,十进制制的值为883927720,再再加上5就就是839927255罗1)给定结结构strruct A chhar tt:4; chhar kk:4; unnsignned sshortt i:88; unnsignned llong m;问siizeoff(A) = ?给定结构sstrucct A chhar tt:4; 4位 chhar kk:4; 4位 unnsignned sshortt i:88; 8位位 unnsignned llong m; / 偏移移2字节保保证4字节节对齐; / 共8字字节2)下面的的函数
10、实现现在一个数数上加一个个数,有什什么错误?请改正。int aadd_nn ( iint nn ) sstatiic innt i = 1000; ii += n; rreturrn i;当你第二次次调用时得得不到正确确的结果,难难道你写个个函数就是是为了调用用一次?问问题就出在在 staatic上上?/ 帮忙忙分析一下下#incllude#incllude #incllude #incllude #incllude #incllude typeddef sstrucct AAA iint bb1:5; iint bb2:2;AA;void mainn() AAA aaa; cchar cc1
11、100; strccpy(ccc,0012344567889abccdefgghijkklmnoopqrsstuvwwxyz); meemcpyy(&aaa,cc,sizeeof(AAA); ccout aaa.b11 eendl; ccout aaa.b22 0 & b0 &(*ca | *cb) | (aa0 & ba | *cb);分析:strucct biit iint aa:3; iint b:2; iint cc:3; ; int mmain() bitt s; chaar *cc=(chhar*)&s; cooutsizeeof(bbit)enddl; *c=0x999; coo
12、ut s.a endll ss.bendlls.ceendl; int a=-11; prrintff(%xx,a); retturn 0; 输出为什么么是41-1-4fffffffff因为0x999在内存存中表示为为 1000 11 001 , a = 0001, bb = 111, cc = 1100当c为有符符合数时, c = 1000, 最高高1为表示示c为负数数,负数在在计算机用用补码表示示,所以cc = -4;同理理 b = -1;当c为有符符合数时, c = 1000,即 cc = 44,同理 b = 3位域 : 有些信息在在存储时,并并不需要占占用一个完完整的字节节,而只需需占
13、几个或或一个二进进制位。例例如在存放放一个开关关量时,只只有0和11 两种状状态,用一一位二进位位即可。为为了节省存存储空间,并并使处理简简便,语语言又提供供了一种数数据结构,称称为“位域”或“位段”。所谓“位域”是把一个个字节中的的二进位划划分为几个个不同的区区域, 并并说明每个个区域的位位数。每个个域有一个个域名,允允许在程序序中按域名名进行操作作。这样就就可以把几几个不同的的对象用一一个字节的的二进制位位域来表示示。一、位位域的定义义和位域变变量的说明明位域定义义与结构定定义相仿,其其形式为: strucct 位域域结构名 位域列列表 ; 其中位域列列表的形式式为: 类类型说明符符 位域
14、名名:位域长长度 例如: strucct bss int aa:8; int bb:2; int cc:6; ; 位域变量的的说明与结结构变量说说明的方式式相同。可可采用先定定义后说明明,同时定定义说明或或者直接说说明这三种种方式。例例如: strucct bss int aa:8; int bb:2; int cc:6; dataa; 说明datta为bss变量,共共占两个字字节。其中中位域a占占8位,位位域b占22位,位域域c占6位位。对于位位域的定义义尚有以下下几点说明明: 1. 一个个位域必须须存储在同同一个字节节中,不能能跨两个字字节。如一一个字节所所剩空间不不够存放另另一位域时时,
15、应从下下一单元起起存放该位位域。也可可以有意使使某位域从从下一单元元开始。例例如: strucct bss unsiggned a:4 unsiggned :0 /*空域*/ unsiggned b:4 /*从下下一单元开开始存放*/ unsiggned c:4 在这个位域域定义中,aa占第一字字节的4位位,后4位位填0表示示不使用,bb从第二字字节开始,占占用4位,cc占用4位位。 2. 由于于位域不允允许跨两个个字节,因因此位域的的长度不能能大于一个个字节的长长度,也就就是说不能能超过8位位二进位。 3. 位域域可以无位位域名,这这时它只用用来作填充充或调整位位置。无名名的位域是是不能使用
16、用的。例如如: strucct k int aa:1 int :2 /*该2位不不能使用*/ int bb:3 int cc:2 ; 从以上分析析可以看出出,位域在在本质上就就是一种结结构类型, 不过其成成员是按二二进位分配配的。 二、位域的的使用位域域的使用和和结构成员员的使用相相同,其一一般形式为为: 位域域变量名位域名 位域允许许用各种格格式输出。 main() strucct bss unsiggned a:1; unsiggned b:3; unsiggned c:4; bitt,*pbbit; bit.aa=1; bit.bb=7; bit.cc=一五; pri改错:#incllu
17、de int mmain(voidd) iint *p; iint aarr1100; pp = &arr; rreturrn 0;解答:搞错了,是是指针类型型不同,int *p; /二级级指针&arr; /得得到的是指指向第一维维为1000的数组的的指针#incllude int mmain(voidd) int *p, *q;int aarr1100;q = aarr;p = &q;returrn 0;下面这个程程序执行后后会有什么么错误或者者效果: #deffine MAX 255 int mainn() unnsignned cchar AMAAX,ii;/ii被定义为为unsiign
18、edd chaar foor (ii=0;ii=MAAX;i+) Ai=i;解答:死循循环加数组组越界访问问(C/CC+不进进行数组越越界检查)MAX=2255 数组A的下下标范围为为:0.MAX-1,这是是其一.其二.当ii循环到2255时,循环内执执行: A2255=255;这句本身没没有问题.但是返返回forr (i=0;i=MAXX;i+)语句时时,由于unssigneed chhar的取取值范围在在(0.255),i+以后i又又为0了.无限循循环下去.strucct naame1 chhar str; shhort x; innt num;strucct naame2 chhar s
19、str; innt nuum; shhort x;sizeoof(sttructt namme1)=8,siizeoff(strruct namee2)=112在第二个结结构中,为为保证nuum按四个个字节对齐齐,chaar后必须须留出3字字节的空间间;同时为为保证整个个结构的自自然对齐(这这里是4字字节对齐),在在x后还要要补齐2个个字节,这这样就是112字节。intell:A.c 和和B.c两两个c文件件中使用了了两个相同同名字的sstatiic变量,编译的时时候会不会会有问题?这两个sstatiic变量会会保存到哪哪里(栈还还是堆或者者其他的)?statiic 的全全局变量,表表明这个变
20、变量仅在本本模块中有有意义,不不会影响其其他模块。他们都放在在数据区,但但是编译器器对他们的的命名是不不同的。如果要使变变量在其他他模块也有有意义的话话,需要使使用exttern关关键字。strucct s11 intt i: 8; intt j: 4; intt a: 3; douuble b;strucct s22 intt i: 8; intt j: 4; douuble b; intt a:33;printtf(ssizeoof(s11)= %dn, siizeoff(s1);printtf(ssizeoof(s22)= %dn, siizeoff(s2);resullt: 116,
21、224第一个sttructt s1 intt i: 8; intt j: 4; intt a: 3; douuble b;理论上是这这样的,首首先是i在在相对0的的位置,占占8 位一一个字节,然然后,j就就在相对一一个字节的的位置,由由于一个位位置的字节节数是4位位的倍数,因因此不用对对齐,就放放在那里了了,然后是是a,要在在3位的倍倍数关系的的位置上,因因此要移一一位,在一一五位的位位置上放下下,目前总总共是一八八位,折算算过来是22字节2位位的样子,由由于douuble是是8字节的的,因此要要在相对00要是8个个字节的位位置上放下下,因此从从一八位开开始到8个个字节之间间的位置被被忽略,直
22、直接放在88字节的位位置了,因因此,总共共是16字字节。第二个最后后会对照是是不是结构构体内最大大数据的倍倍数,不是是的话,会会补成是最最大数据的的倍数上面是基本本问题,接接下来是编编程问题:本人很弱,这这几个题也也搞不定,特特来求救:1)读文件件filee1.txxt的内容容(例如):123456输出到fiile2.txt:563412(逆序)2)输出和和为一个给给定整数的的所有组合合例如n=555=1+44;5=22+3(相相加的数不不能重复)则输出1,4;22,3。望高手赐教教!第一题,注注意可增长长数组的应应用.#incllude #incllude int mmain(voidd)
23、int MAX = 100;int *a = (intt *)mmallooc(MAAX * sizeeof(iint);int *b;FILE *fp11;FILE *fp22;fp1 = foppen(a.txxt,r);if(fpp1 = NULLL)prinntf(erroor1); eexit(-1); ffp2 = foppen(b.txxt,w);if(fpp2 = NULLL)prinntf(erroor2); eexit(-1);int ii = 00; iint jj = 00;whilee(fsccanf(fp1,%d,&ai) != EEOF)i+;j+;if(i =
24、MMAX)MAX = 2 * MAXX;b = (int*)reaallocc(a,MMAX * sizzeof(int);if(b = NNULL)printtf(eerrorr3);exit(-1);a = bb;for(;-j = 00;) fpprinttf(fpp2,%dn,ajj);fclosse(fpp1);fclosse(fpp2);returrn 0;第二题.#incllude int mmain(voidd)unsiggned longg intt i,jj,k;printtf(ppleasse innput the numbbernn);scanff(%dd,&ii);
25、iif( ii % 22 = 0) jj = ii / 22;elsej = ii / 22 + 11;printtf(TThe rresullt iss n); ffor(kk = 00; k j; k+) prinntf(%d = %d + %ddn,i,k,i - k);returrn 0;#incllude void mainn()unsiggned longg intt a,ii=1;scanff(%dd,&aa);if(a%2=00) for(i=1;ia/2;i+) prinntf(%d,a,a-i);elsefor(ii=1;ii=a/2;i+) pprinttf( %d, %
26、d,i,a-i);兄弟,这样样的题目若若是做不出出来实在是是有些不应应该, 给给你一个递递规反向输输出字符串串的例子,可谓是反反序的经典典例程.void inveerse(charr *p) iif( *p = = 0 ) returrn; iinverrse( p+1 ); pprinttf( %c, *p );int mmain(int argcc, chhar *argvv) iinverrse(abc0); rreturrn 0;借签了楼上上的“递规反向向输出”#incllude void testt(FILLE *ffreadd, FIILE *fwriite) cchar buf1
27、0244 = 0; iif (!fgetts(buuf, ssizeoof(buuf), freaad) rreturrn; ttest( freead, fwriite ); ffputss(buff, fwwritee);int mmain(int argcc, chhar *argvv) FFILE *fr = NUULL; FFILE *fw = NUULL; ffr = fopeen(ddata, rrb); ffw = fopeen(ddataoout, wbb); ttest(fr, fw); ffclosse(frr); ffclosse(fww); rreturrn 0;在对
28、齐为44的情况下下strucct BBBB loong nnum; chhar *namee; shhort int dataa; chhar hha; shhort ba55;*p;p=0x110000000;p+0x2200=_;(Ulonng)p+0x2000=_;(charr*)p+0x2000=_;希望各位达达人给出答答案和原因因,谢谢拉拉解答:假设设在32位位CPU上上,sizeoof(loong) = 4 byteessizeoof(chhar *) = 4 byytessizeoof(shhort int) = ssizeoof(shhort) = 22 byttessizeo
29、of(chhar) = 1 bytees由于是4字字节对齐,sizeoof(sttructt BBBB) = sizeeof(*p) = 4 + 4 + 2 + 1 + 1/*补齐*/ + 22*5 + 2/*补齐*/ = 224 byytes (经DDev-CC+验证证)p=0x110000000;p+0x2200=_; = 0x110000000 + 0x2200*224(Ulonng)p+0x2000=_;= 0x110000000 + 0x2200(charr*)p+0x2000=_; = 0x110000000 + 0x2200*44你可以参考考一下指针针运算的细细节写一段程序序,找
30、出数数组中第kk大小的数数,输出数数所在的位位置。例如如2,44,3,44,7中中,第一大大的数是77,位置在在4。第二二大、第三三大的数都都是4,位位置在1、33随便输出出哪一个均均可。函数数接口为:int findd_ordderk(consst innt* nnarryy,connst iint nn,connst iint kk) 要求算法复复杂度不能能是O(nn2)谢谢!可以先用快快速排序进进行排序,其其中用另外外一个进行行地址查找找代码如下,在在VC+6.0运运行通过。给给分吧-/快速排排序#inclludeusinggnameespaccestdd;intPaartittion
31、(intt*L,iintloow,innt hiigh)intteemp = Lllow;intptt = LLloww;whilee (loow highh)whilee (loow = ppt)-higgh;Lloww = Lhiigh;whilee (loow highh & Lloow = ptt)+loww;Lloww = tempp;Lloww = tempp;returrnloww;voidQQSortt (innt*L,intllow,iint hhigh)if (llow higgh)intpll = PPartiitionn (L,low,highh);QSortt (L,
32、low,pl - 1);QSortt (L,pl + 1,hhigh);intmaain ()intnaarry100,adddr1000;intsuum = 1,t;cout Inpuut nuumberr: t;whilee (t != -1)narryysumm = t;addrsum - 1 = tt;sum+;cin t;sum -= 1;QSortt (naarry,1,suum);for (int i = 1; ii = sum;i+)cout nnarryyi t;cout eendl;intk;cout Pleaase iinputt plaace yyou wwant: k
33、;intaaa = 11;intkkk = 00;for (;)if (aaa = k)breakk;if (nnarryykk != narrrykkk + 11)aa += 1;kk+;cout The NO. k nuumberr is: narrryssum - kk endll;cout And itss plaace iis: ;for (i = 0;i suum;i+)if (aaddri = naarrysum - kkk)cout ii t;returrn0;1、找错Void testt1()char striing110;char* strr1=0012344567889;
34、strcppy(sttringg, sttr1);/ 溢溢出,应该该包括一个个存放0的字字符strring11Void testt2()char striing110, str1110;for(II=0; I100;I+)str1i =a;strcppy(sttringg, sttr1);/ II,i没有有声明。Void testt3(chhar* str11)char striing110;if(sttrlenn(strr1)=10)/ 改成成10,字符溢出出,将sttrlenn改为siizeoff也可以strcppy(sttringg, sttr1);2.void g(innt*);int
35、 mmain()int lline10,i;int *p=liine; /p是是地址的地地址for (i=0;i100;i+)*p=i;g(&p);/ 数组对应应的值加11for(ii=0;ii10;i+)printtf(%dn,linnei);returrn 0;void g(innt*pp)(*p)+;(*p)+;/ 无效输出:12 3 4 5 6 7 8 9 103. 写出出程序运行行结果int ssum(iint aa)auto int c=0;statiic innt b=3;c+=1;b+=2;returrn(a+b+c);void mainn()int II;int aa=2;for(II=0;II5;II+)printtf(%d, summ(a);/ sttaticc会保存上上次结果,记记住这一点点,剩下的的自己写输出:8,10,112,144,16,4.int ffunc(int a)int bb;switcch(a)case 1: 330;case 2: 2
限制150内