C语言笔试面试题.docx
表示已有答案表示没有处理表示答案不确定C+笔试题1.多态类中的虚函数表是Compile-Time,还是Run-Time时建立的?答案:虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数 组.而对象的隐藏成员一虚拟函数表指针是在运行期一也就是构造函数被调用时进行初始化的,这是 实现多态的关键.3 .main主函数执行完毕后,是否可能会再执行一段代码?(朗讯的一道笔试题)答案:可以,可以用onexit注册一个函数,它会在main之后执行;如果你需要加入一段在main退出后执行的代码,可以使用atexit ()函数,注册一个函数。语法:4include <stdlib. h>int atexit(void ("function")(void);ttinclude <stdlib. h>#include <stdio. h>void fnl( void ), fn2( void ), fn3( void ), fn4( void );int main( void )(atexit(fnl);atexit ( fr)2 );atexit( fn3 );atexit( fn4 );printf( "This is executed first. n* );void fnl ()(printf( "next.n");void fn2()(printf( "executed ");void fn3()(printf( "is ");Jvoid fn4()(printf( "This ");结果:This is executed first.This is executed next.4 .一个父类写了一virtual函数,如果子类覆盖它的函数不加virtual ,也能实现多态?在子类的空间里,有没有父类的这个函数,或者父类的私有变量?(华为笔试题)答案:只要基类在定义成员函数时已经声明了 virtue关键'九在派生类实现的时候覆盖该函数时, virtue关罐字可加可不加,不影响多态的实现。子类的空间里有父类的所有变量(static除外).5 .给一个字符串、例如“ababc”要求返回“ab” .因为“ab”连续重复出现且最长。用C/C+语言写一函数完成该算法,给出复杂度6 .对序列 1、1、2、3、5、8、13. 是 Fab.数列2、3、5、13.是Fab.质数数列,因为他们与自己前面的Fab.数列都互质给出k,返回第k小的Fab.质数7 . 101个硬币100真、1假,真假区别在于重量。请用无祛码天平称两次给出真币重还是假币 重的结论。8 .完成字符串拷贝可以使用sprintf、strcpy及memcpy函数,请问这些函数有什么区别,你喜欢使用哪个,为什么?答案:这些函数的区别在于实现功能以及操作对象不同。1. strcpy函数操作的对象是字符串,完成从源字符串到目的字符串的拷贝功能。2. snprintf函数操作的对象不限于字符串:虽然目的对象是字符串,但是源对象可以是字符串、也 可以是任意基本类型的数据。这个函数主要用来实现(字符串或基本数据类型)向字符串的转换功 能。如果源对象是字符串,并且指定%s格式符,也可实现字符串拷贝功能。3. memcpy函数顾名思义就是内存拷贝,实现将一个内存块的内容复制到另一个内存块这功 能。内存块山其首地址以及长度确定。程序中出现的实体对象,不论是什么类型,其最终表现就是 在内存中占据一席之地(一个内存区间或块)。因此,memcpy的操作对象不局限于某一类数据类型, 或者说可适用于任意数据类型,只要能给出对象的起始地址和内存长度信息、并且对象具有可操作 性即可。鉴于memcpy函数等长拷贝的特点以及数据类型代表的物理意义,memcpy函数通常限于同 种类型数据或对象之间的拷贝,其中当然也包括字符串拷贝以及基本数据类型的拷贝.对于字符串拷贝来说,用上述三个函数都可以实现,但是其实现的效率和使用的方便程度不同: strcpy无疑是最合适的选择:效率高且调用方便。 snprintf要额外指定格式符并且进行格式转化,麻烦且效率不高。 memcpy虽然高效,但是需要额外提供拷贝的内存长度这一参数,易错且使用不便;并且如 果长度指定过大的话(最优长度是源字符串长度+1),还会带来性能的下降。其实strcpy 函数般是在内部调用memcpy函数或者用汇编直接实现的,以达到高效的目的。因此,使 用memcpy和strcpy拷贝字符串在性能上应该没有什么大的差别。对于非字符串类型的数据的复制来说,strcpy和snprintf 一般就无能为力了,可是对memcpy 却没有什么影响。但是,对于基本数据类型来说,尽管可以用memcpy进行拷贝,由于有赋值 运算符可以方便且高效地进行同种或兼容类型的数据之间的拷贝,所以这种情况下memcpy几 乎不被使用。memcpy的长处是用来实现(通常是内部实现居多)对结构或者数组的拷贝,其H 的是或者高效,或者使用方便,甚或两者兼有。9 .变录的声明和定义有什么区别?10 .请写出下面代码在32位平台上的运行结果,并说明sizeof的性质:#include <stdio. h>9include <stdlib.h>int main(void)char a30;printf (飞dn”, sizeof (a);char *b = (char *)malloc (20 * sizeof (char);printf("%dn”, sizeof(b);printf("%dn”, sizeof(a3);printf("%dn”, sizeof(b+3);printf("%dn", sizeof(*(b+4);return 0 ;12 .请完成以下题目。注意,请勿直接调用ANSI C函数库中的函数实现。a)请编写一个C函数,该函数给出一个字节中被置1的位的个数,并请给出该题的至少一个不同 解法。第,种 unsigned int TestAsOneO(char log)(int i;unsignedintnum=0,val;for(i=0;i<8;i+)(val = log » i; 移位val& 二0x01; 与 1 相与if(val)num+; return num;)第二种 unsigned int TestAsOnel (char log)(int i;unsigned int num=0, val;for (i=0;i<8;i+)(val =Clog)» i; 反码?val&=0x00;与。相与if (!val) num+; return num;)b)请编写一个c函数,该函数将给定的一个字符串转换成整数。 int Invert(char *str)(int num=0;while(*str!=, 0*)(int digital=*str-48;num=num*10+digital;str=str+l;)return num;c)请编写一个C函数,该函数将给定的一个整数转换成字符串。 voidIntToCharChange(intnum, char* pval)char strval100;int i,j;int valO=0;int vail=o;valO =num;for (i=0;i<100;i+)(vail =valO %10;/取余valO =valO /10;取整strvali=vail +48; 数字一字符if(val0<10)(i+;strvali=valO +48;break;for(j=0;j<=i;j+)倒置(pvalj= strvali-j;pvalj=,0';d)请编写一个C函数,该函数将一个字符串逆序。voidAnt i toneValue(char*father, char* child)( int i;char source100;int j =0;while(fatherj) 放入 source, j为长度 sourcej= fatherj;j+;if(j > 99) (return;sourcej=' 0'for (i=0; i<j; i+)(childi=sourcej-i-l;反序childi='0'e)请编写一个C函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。 int search (char *cpSource, int n, char ch) 起始地址,搜索长度,目标字符 for(i=0; i<n && *(cpSource+i) != ch; +i);return i;)f)请编写一个C函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一 字符组成的。int ChildString (char*p) 自己写(Char *q=p;int stringlen=O, i=0,j=l,len=0,maxlen=l;while(*q!=, 0")不能用 strlen,求得长度 stringlen(Stringlen+;q+;)while( i< Stringlen )(if(*(p+i)-=*(p+j)&&j< Stringlen)(len+;统计子串长度i+;j+;)else(if (len>maxlen)/统计最大子串长度(maxlen=len+l;len=0;else len=0;)i+;j+;return maxlen;)给出演示上述函数功能的一个简单程序,并请编写对应的Makefile文件13 .我们需要编写一个图形相关的应用程序,需要处理大量图形(Shape)信息,图形有矩形 (Rectangle),正方形(Square),圆形(Circle)等种类,应用需要计算这些图形的面积,并且可能 需要在某个设备上进行显示(使用在标准输出上打印信息的方式做为示意)。a)请用面向对象的方法对以上应用进行设计,编写可能需要的类b)请给出实现以上应用功能的示例性代码,从某处获取图形信息,并且进行计算和绘制c)如果你的Square继承自Rectangle,请给出理山,如果不是,请给出理由,并且请比较两种方式的优劣d)请问你所编写的类,在如下代码中会有何表现,请解释void test rectangle area(Rectangle& r)r. set_width(10);r. set_height (15);assert (r. areaO = 150);14 .假设现有一个单向的链表,但是只知道只有一个指向该节点的指针p,并且假设这个节点不是尾节点,试编程实现删除此节点参考:将卜一个节点的内容复制到本节点上,然后删除下一个节点;15 .写一个程序,把一个100以内的自然数分解因数。(自然数分解因数就是将一个自然数 分解为几个素数的乘积,提示,由于该数不是很大,所以可以将质数保存在数组中,以加快计 算速度)16 .编写一个Identify的分配、释放的函数,为1一10000之间的自然数。17 .分别实现itoa和atoi.18 . Consider the following code:#include <stdio. h>ttinclude <string. h>int main(int argc, char *argv) int i = 1;char buf4;strcpy(buf, "AAAA");printf("%dn", i);return 0;a) When compiled and executed on x86, why does this program usually not output what the programmer intended? 在x86上为什么不能得到预期结果b) Name several ways in which the security problem that causes this program not to output what the programmer intended can be prevented WITHOUT changing the code.参考:第一个问题:32位情况:x86下,栈方向向上生长.在main的栈中,先分配i空间(4byte),然后分配4个字节的buf (地址在 i的上面,比i小).strcpy越界,用0把buf开始的第4(0开始)个字节覆盖掉了.而x86是LSB排列 顺序,所以真好覆盖了 i的内个数字1.所以显示出数字0.16位情况同样分析即可.第2问?19 . int w=l, x=2, y=3, z=4;m=(w<x)?w:x;m=(m<y)?m:y;m=(m<2)?m:z;printf m);说出结果答案:120 .说出结果?#include <stdio. h>main()FILE *fp;int i, a4 = l, 2, 3, 4, b;fp=fopen("data. dat", "wb"); 这里帮忙解释一下for(i=0;i<4;i+)fwrite(&ai, sizeof (int), 1, fp);这里也帮忙看一下 fclose(fp);fp二fopen("data. dat", "rb");fseek(fp, -2L*sizeof (int), SEEK_END);还有这里fread(&b, sizeof (int), 1, fp);这里还有也看一下fclose(fp);printf("b=%dn”, b);21 .有双向循环链表结点:(华为面试题)typedef struct node int date;struct node *front, *next;_Node;有两个双向循环链表A, B,知道其头指针为:pHeadA, pHeadB,请写一函数将两上链表中date值相 同的结点删除参考算法:1 .取出A的一个元素d2 .收集B中有相同元素d的结点到垃圾箱,并从B里删除3 .收集A中有相同元素d的结点到垃圾箱,并从A里删除4 .删除垃圾箱中的所有元素5 .A链的指针指向下一个6 .重复广5,直到A链循环到头了注意的是第3步,在2步执行后垃圾箱不为空时才执行。上述算法还可以做一点点优化:1.加入两个变量cA,cB,分别记录当前A中和B中的元素个数每次从较长者中取出一个元素来,先从较小者中找起若没有,则不必在较长者中浪费时间了#include<iostream. h>?struct NODE int date;NODE *front, *next;);void redel(NODE *&ahead, NODE *&bhead)(int boy=0;NODE *pa=ahead, *pb=bhead,*paa, *paaa, *paaaa, *pbb;while(pa->next!=ahead) (int boys=pa->date;取 pa 中一个值paaaa=pa;paa=pa;pb=bhead;while(pb->next!=bhead)if (boys=pb->date)如果 pa, pb 中有值相同cout<<endl;cout«*delete B: *«paa->date«* if(pb=bhead) (boy=l;pb->front->next=pb->next; pb->next->front=pb->front; bhead=bhead->next;pbb=pb; pb=pb->next; delete pbb;) else ( boy=l; pb->front->next=pb->next; pb->next->front=pb->front; pbb=pb;pb=pb->next; delete pbb;elsepb=pb->next;)while(paa->next!=ahead && boy=l)(if(paa->date=boys)(cout<<*delete A: *<<paa->date«>r if(paa=pa) (pa=pa->next; ahead=pa;paa->front->next=paa->next; paa->next->front=paa->front; paaa=paa;paa=paa->next; delete paaa;)else(paa->front->next=paa->next; paa->next->front=paa->front; paaa=paa;paa=paa->next; delete paaa;elsepaa=paa->next;boy=0;if(paaaa=pa) pa=pa->next;cout<<endl;int main()(NODE *A, *pHeadA, *B, *pHeadB;A=new NODE;B=new NODE;pHeadA=A;pHeadB=B;for (int i=l; i<21;+i)生成链表A,并赋初值!( A->date=i; A->next=new NODE; A->next->front=A; A=A->next;)A=A->front;delete A->next;A->next=pHeadA;pHeadA->front=A;for (int i=l; i<33;i+=2)生成链表 B,并赋初值!(B->date=i;B->next=new NODE;B->next->front=B; B=B->next;B=B->front;delete B->next;B->next=pHeadB;pHeadB->front=B;redel (pHeadA, pHeadB);调用函数删除相同结点!)22.char * GetStr ()(char *tmp;tmp = "123" return tmp;printf("%s”, GetStr();)会输出123吗? 123创建在堆上还是栈上呢? 123的空间是什么时候释放的?参考:"123”是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈 在程 序结束时自动释放23.1)字符指针、浮点数指针、以及函数指针这三种类型的变量哪个占用的内存最大?为什么? 答案:指针变量也占用内存单元,而且所有指针变量占用内存单元的数量都是相同的。就是说,不 管是指向何种对象的指针变量,它们占用内存的字节数都是样的,并且要足够把程序中所能用到 的最大地址表示出来(通常是一个机器字长)。2)类ClassB从ClassA派生,那么ClassA *a = new ClassB();试问该表达是否合法?为什 么?答案:派生类的指针指向基类的对象是错误的,不能通过编译的;基类的指针可以指向派生类的对 象,调用派生类的函数鸡是动物,没错。(动物的指针指向鸡的实例)鸡可以执行所有动物都具有的方法,例如“死亡”反过来,动物一定是鸡吗?(鸡的指针指向动物或者动物的某个派生类的实例)动物都能执行鸡的某个方法吗?比如说“下蛋”?3)如果ClassA中定义并实现虚函数int func (void), ClassB中也实现该函数,那么上述变量 a->func()将调用哪个类里面的函数?如果int func(void)不是虚函数,情况又如何?为什 么?答案:第一问调用的是B的。第二问调用A的。虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果如果没有定义成虚函数:class Apublic:void print () cout<<w This is AM «endl;);class B:public Apublic:void print() cout<<w This is B* «endl;);int main()/为了在以后便于区分,我这段main。代码叫做mainlA a; B b;A* pl=&a;A* p2=&b:pl->print();p2->print();)结果是两个This is A如果定义成虚函数:class Apublic:virtual void print() cout«w This is Aw «endl: 现在成了虚函数了);class B:public A(public:void print () cout«w This is BM «endl; 这里不需要在前面加上关犍字virtual,只需在 把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数);再运行main输出的结果就是This is A和This is B测试:4) char *p, a16 8;问:p=a是否会导致程序在以后出现问题?为什么?参考:这个不会导致出现问题,但是要注意P的使用,如al2等价的为*(*(p+l)+2)而不是*(p+ll),会的,这样会出现编译错误 正确的是:char a5 5 ; char (*p) 5; p=a;如下所述的if else和switch语句哪个的效率高?为什么?5)在同个进程中,个模块是否可以通过指针操作破坏其它模块的内存,为什么?(华为)6)应用程序在运行时的内存包括代码区和数据区,其中数据区又包括哪些部分?参考:对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数 据区。动态数据区一般就是“堆栈” o栈是一种线性结构,堆是一种链式结构。进程的每个线程都 有私有的“栈”。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。 程序通过堆栈的基地址和偏移量来访问本地变量。24 .Assignment 2: Picture ProcessingUse C+, Java, or similar languages or/and any middleware such as EJB and J2EE to process a picture with a high resolution (3 Mega Pixels for example). Use some methodologies to degrade the resolution of the picture to make it quick er for browsing. Then divide the degraded picture into 9 sectors equally. Cli ck any of the 9 sectors will result a detailed picture for this sector with t he same resolution as that of the original picture. This assignment is design ed for you to demonstrate your ability to handle pictures.25 .用|&实现一个WORD (2个字节)的高低位交换! int main ()(unsignedshorta=OxABCD;unsignedshortb;unsignedshortc, d;b = (a « 8)&0xff00;c = (a » 8)&0x00ff;d = bc;printf ('n%x”, b);printf ("n%x”, c);printf('n%x”, d);return 0;结果是CDAB2俩个字节是16位前八位为高位后八位为低位然后结合26 .要开辟Pl, P2, P3, P4内存来做缓冲,大小自定,但这四个缓冲的大小要一样,并且是连续的27 .有一浮点型数组A,用C语言写一函数实现对浮点数组A进行降序排序,并输出结果,要求要 以数组A作为函数的入口.(建议用冒泡排序法) void BubbleSort(double arr, int n) int i, j;int exchange =1; 交换标志for (i=l; i<n; i+) 最多做 n-l 趟排序exchanged;本趟排序开始前,交换标志应为假for(j=n-l; j>=i; j)对当前无序区Ri. n自下向上扫描if (arrj+l > airj) 交换记录arr0 =arrj+1;/R0不是哨兵,仅做暂存单元arrj+l=arrj;arrj=arr0;exchange=l; 发生了交换,故将交换标志置为真if(!exchange) 本趟排序未发生交换,提前终止算法 return;)endfor (外循环)28 .找错:#include <string. h>#include <stdio. h>class Base private:char * name;public:Base (char * className)(name = new charstrlen(className);strcpy(name, className);Base ()delete name; char * copyName()char newname 256;strcpy(newname, name);return newname;char * getName()return name;static void print(Base base)printf("name: %sn , base, name););class Subclass : public Basepublic:Subclass(char * className) : Base(className) int main ()Base * pBase = new Subclass("test");Base:print (*pBase);printf (,zname: %sn”, pBase->getName();printf (zznew name: %sn,pBase->copyName();return 0;29 .编写一个函数,函数接收一个字符串,是由十六进制数组成的一组字符串,函数的功能是 把接到的这组字符串转换成十进制数字.并将十进制数字返回.答案:BOOL HexToDec( LPCTSTR shex, int& idee )(int i, mid;int len = lstrlen( shex );if( len>8 )return FALSE;mid =0; idee =0;for (i=0;i<len;i+)if (shexi>='O'&&shexi<='9')mid=shexi-'O'elseif (shexi>=,a* &&shexi<=, f?)mid=shexi -'a'+10;elseif(shexi>=,A* &&shexi<=* F*)mid=shexi -' A'+10;elsereturn FALSE;mid «=(len-i-1) «2);/移位表示变为2的n次方倍idee =idc+mid;)return TRUE;)30 .编写一个函数将一条字符串分成两部分,将前半部分按ASCH码升序排序,后半部分不 变,(如果字符串是奇数则中间的字符不变,)最后再将前后两部分交换,然后将该字符 串输出,测试字符串 “ADZDDJKJFIEJHGI”31 .找错Void testl() char string10;char* strl="0123456789”;strepy(string, strl);)Void test2() char string10, strl10;for(1=0; K10;I+)strli ='a' ;strepy (string, strl):Void test3(char* strl) char string10;if(strlen(strl)<=10) strcpy(string, strl);)32 . 找错#define MAX_SRM 256 DSN get_SRM_no() static int SRMno;int I;for(1=0;ISRM_no %= MAX_SRM; if(MY_SRM. state=IDLE) break; ) if(I>=MAX_SRM) return (NULL_SRM); elsereturn SRM_no;33 .写出程序运行结果int sum(int a) auto int c=0;static int b=3;c+=l;b+=2;return(a+b+C);void main() int I;int a=2;for(I=0;I<5;I+) printf(*%d,sum(a); 34 . int func(int a) int b;switch(a) case 1: 30;case 2: 20;case 3: 16; default: 0 return b;则func=?35 :int a3;a0=0; al=l; a2=2;int *p, *q;P=a;q=&a ;则 aq-p=?36 .定义int *a3 4,则变量占有的内存空间为:37 .编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。如输入2004年12 月31日23时59分59秒,则输出2005年1月1日0时0分0秒。38 .写一个函数,判断一个int型的整数是否是2的事,即是否可以表示成2cx的形式(不可 以用循环)我只知道是用递推,大概写了一下,如下:int IsTwoPow(int s) if(s=l)return FALSE;s=s»l;if(s>l)IsTwoPow(s);return (s=l)?TRUE:FALSE;大概是这个意思,但是这一句似乎不该这么返回!39 A, B从一堆玻璃球(共100个)里向外拿球,规则如下:(1)A先拿,然后一人一次交替着拿;(2)每次只能拿1个或2个或4个;(3)谁拿最后一个球,谁就是最后的失败者;问A, B谁将是失败者?写出你的判断步骤。40 .已知:无序数组,折半查找,各元素值唯一。函数原型是:Binary_Seach(int array , int iValue, int iCount)array是数组,在里面用折半查找的方法找等于iValue的值,找到返回1否则0, iCount 是元素个数41 .统计一个字符串中字符出现的次数42 . 100位以上的超大整数的加法(主要考虑数据结构和加法的实现)43 .对如下电文:"CASTCASTSATATATASA”给出 Huffman 编码。44 . int (* (*f) (int, int) (int)表示什么含义?45 . x=x+l, x+=l, x+,为这三个语句的效率排序。并说明为什么。46 .中缀表达式A-(B+C/D)*E的后缀形式是什么?47 .struct S1 char c;int i;);sizeof(SI) = ?class Xpublic:X();virtual X();void myMemberFunc();static void myStaticFunc();virtual void myVirtualFunc0;private:int i;char * pstr;char a;sizeof(X) = ?48 .找出两个字符串中最大子字符串,如"abractyeyt", "dgdsaeactyey”的最大子串为"acty et*49 .有一百个整数,其中有负数,找出连续三个数之和最大的部分.50 .写一程序实现快速排序,假设数据输入为一文件快速算法描述如下Algorithm PartitionInput: sequence aO, ., an-l with n elementsOutput: permutation of the sequence such that all elements aO, ., aj are les s than or equal to all elements ai, ., an-l (i > j)Method:choose the element in the middle of the sequence as comparison element x let i = 0 and