培训用C面试经典题目.docx

上传人:b****6 文档编号:7326184 上传时间:2023-01-23 格式:DOCX 页数:41 大小:86.60KB
下载 相关 举报
培训用C面试经典题目.docx_第1页
第1页 / 共41页
培训用C面试经典题目.docx_第2页
第2页 / 共41页
培训用C面试经典题目.docx_第3页
第3页 / 共41页
培训用C面试经典题目.docx_第4页
第4页 / 共41页
培训用C面试经典题目.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

培训用C面试经典题目.docx

《培训用C面试经典题目.docx》由会员分享,可在线阅读,更多相关《培训用C面试经典题目.docx(41页珍藏版)》请在冰豆网上搜索。

培训用C面试经典题目.docx

培训用C面试经典题目

以下是求一个数的平方的程序,请找出错误:

#defineSQUARE(a)((a)*(a))

inta=5;

intb;

b=SQUARE(a++);

请问下面程序有什么错误?

#defineMax_CB500

voidLmiQueryCSmd(StructMSgCB*pmsg)

{

unsignedcharucCmdNum;

......

for(ucCmdNum=0;ucCmdNum

{

......;

}

死循环(unsignedchar0到255)

19.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。

写出C程序。

循环链表,用取余操作做

#include

#defineNULL0

#defineTYPEstructstu

#defineLENsizeof(structstu)

structstu

{

intdata;

structstu*next;

};

TYPE*line(intn)

{

intsum=1;

structstu*head,*pf,*pb;

inti;

for(i=0;i

{

pb=(TYPE*)malloc(LEN);

pb->data=sum;

if(i==0)

pf=head=pb;

else

pf->next=pb;

if(i==(n-1))

pb->next=head;

elsepb->next=NULL;

pf=pb;

sum++;

}

return(head);

}

main()

{

intM,N,x,i;

structstu*p,*q;

printf("pleasescanfMandN(M

scanf("%d%d",&M,&N);

p=line(N);

x=N;

while(x)

{

for(i=1;i

{

p=p->next;

}

q=p->next;

printf("%d\n",q->data);

p->next=p->next->next;

p=p->next;

free(q);

x--;

}

getch();

}

2、有一个16位的整数,每4位为一个数,写函数求他们的和。

解释:

整数110101*********1

和1101+0101+1011+0111

感觉应该不难,当时对题理解的不是很清楚,所以写了一个函数,也不知道对不对。

疑问:

既然是16位的整数,110101*********1是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),使用交换,而且一次只能交换两个数.(华为)

#include

intmain()

{

inta[]={10,6,9,5,2,8,4,7,1,3};

intlen=sizeof(a)/sizeof(int);

inttemp;

for(inti=0;i

{

temp=a[a[i]-1];

a[a[i]-1]=a[i];

a[i]=temp;

if(a[i]==i+1)

i++;

}

for(intj=0;j

cout<

return0;

}

1、写出程序把一个链表中的接点顺序倒排

typedefstructlinknode

{

intdata;

structlinknode*next;

}node;

//将一个链表逆置

node*reverse(node*head)

{

node*p,*q,*r;

p=head;

q=p->next;

while(q!

=NULL)

{

r=q->next;

q->next=p;

p=q;

q=r;

}

head->next=NULL;

head=p;

returnhead;

}

9、写出下列代码的输出内容  

#include  

intinc(inta)  

{return(++a);}  

intmulti(int*a,int*b,int*c)  

{ return(*c=*a**b);} 

typedefint(FUNC1)(intin);  

typedefint(FUNC2)(int*,int*,int*); 

 voidshow(FUNC2fun,intarg1,int*arg2) 

 {   

FUNC1p=&inc;  

 inttemp=p(arg1);  

 fun(&temp,&arg1,arg2);  

 printf("%dn",*arg2);  

}  

main()  

{  

 inta;  //局部变量a为0;

 show(multi,10,&a);   

return0;

  } 

 答:

110 

10、请找出下面代码中的所有错误(题目不错,值得一看)  

说明:

以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”  

#include"string.h"  

main()  

{  

char*src="hello,world";  

char*dest=NULL;  

intlen=strlen(src);  

dest=(char*)malloc(len);  

char*d=dest;  

char*s=src[len]; 

while(len--!

=0)  

d++=s--;  

printf("%s",dest);  

return0;  

}  

答:

  

方法1:

一共有4个错误;  

intmain()  

{  

 char*src="hello,world";  

 intlen=strlen(src);  

 char*dest=(char*)malloc(len+1);//要为分配一个空间 char*d=dest;  

 char*s=&src[len-1];//指向最后一个字符  

 while(len--!

=0)  

 *d++=*s--;  

 *d=0;//尾部要加’\0’  

printf("%sn",dest);   

free(dest);//使用完,应当释放空间,以免造成内存汇泄露

dest=NULL;  //防止产生野指针 

return0; 

 }

方法2:

(方法一需要额外的存储空间,效率不高.) 不错的想法

#include

#include

main()

{

charstr[]="hello,world";

intlen=strlen(str);

chart;

for(inti=0;i

{

t=str[i];

str[i]=str[len-i-1];//小心一点

str[len-i-1]=t;

}

printf("%s",str);

return0;

}

1.用宏定义写出swap(x,y)

答#defineswap(x,y)

x=x+y;

y=x-y;

x=x-y;

2.数组a[N],存放了1至N-1个数,其中某个数重复一次。

写一个函数,找出被重复的数字.时间复杂度必须为o(N)函数原型:

intdo_dup(inta[],intN)

答:

intdo_dup(inta[],intN)//未经调试

{

intsun=0;

intsum2;

for(inti=0;i

{

Sum+=a[i];

}

Sum2=(1+N-1)*N/2;

Return(sum-sum2);

}

下述三个有什么区别?

char*constp;

charconst*p

constchar*p

解答:

char*constp;//常量指针,p的值不可以修改

charconst*p;//指向常量的指针,指向的常量值不可以改

constchar*p;//和charconst*p

3.解释下列输出结果

charstr1[]="abc";

charstr2[]="abc";

constcharstr3[]="abc";

constcharstr4[]="abc";

constchar*str5="abc";

constchar*str6="abc";

char*str7="abc";

char*str8="abc";

cout<<(str1==str2)<

cout<<(str3==str4)<

cout<<(str5==str6)<

cout<<(str7==str8)<

结果是:

0011

解答:

str1,str2,str3,str4是数组变量,它们有各自的内存空间;

而str5,str6,str7,str8是指针,它们指向相同的常量区域。

5.指出下面代码的输出,并解释为什么。

(不错,对地址掌握的深入挖潜)

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].

6.请问以下代码有什么问题:

1).

intmain()

{

chara;

char*str=&a;

strcpy(str,"hello");

printf(str);

return0;

}

答;没有为str分配内存空间,将会发生异常

问题出在将一个字符串复制进一个字符变量指针所指地址。

虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。

Strcpy的在库函数string.h中.程序的主要错误在于越界进行内存读写导致程序崩溃//

2).

char*s="AAA";

printf("%s",s);

s[0]='B';

printf("%s",s);

有什么错?

答:

"AAA"是字符串常量。

s是指针,指向这个字符串常量,所以声明s的时候就有问题。

cosntchar*s="AAA";

然后又因为是常量,所以对是s[0]的赋值操作是不合法的。

1、写一个“标准”宏,这个宏输入两个参数并返回较小的一个。

答:

#defineMin(X,Y)((X)>(Y)?

(Y):

(X))//结尾没有;

1.有以下表达式:

inta=248;b=4;intconstc=21;constint*d=&a;

int*conste=&b;intconst*fconst=&a;

请问下列表达式哪些会被编译器禁止?

为什么?

答:

*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;

*c这是个什么东东,禁止

*d说了是const,禁止

e=&a说了是const禁止

const*fconst=&a;禁止

4.#include

#include

voidgetmemory(char*p)

{

p=(char*)malloc(100);

}

intmain()

{

char*str=NULL;

getmemory(str);

strcpy(p,"helloworld");

printf("%s/n",str);

free(str);

return0;

}

答:

程序崩溃,getmemory中的malloc不能返回动态内存,free()对str操作很危险

3.数组越界问题(这个题目还是有点小险的)

下面这个程序执行后会有什么错误或者效果:

#defineMAX255

intmain()

{

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]

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(x

elsereturn(BSearch(a,x,mid+1,high));

}

2)非递归方法实现:

intBSearch(elemtypea[],keytypekey,intn)

{

intlow,high,mid;

low=0;high=n-1;

while(low<=high)

{

mid=(low+high)/2;

if(a[mid].key==key)returnmid;

elseif(a[mid].key

elsehigh=mid-1;

}

return-1;

}

1.找错题

试题2:

voidtest2()

{

 charstring[10],str1[10];

 inti;

 for(i=0;i<10;i++)

 {

  str1[i]='a';

 }

 strcpy(string,str1);

}

 

试题3:

voidtest3(char*str1)

{

 charstring[10];

 if(strlen(str1)<=10)

 {

  strcpy(string,str1);

 }

}

库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

  2分

voidstrcpy(char*strDest,char*strSrc)

{

 while((*strDest++=*strSrc++)!

='’);

}

 

  4分

voidstrcpy(char*strDest,constchar*strSrc)

//将源字符串加const,表明其为输入参数,加2分

{

 while((*strDest++=*strSrc++)!

='’);

}

 

  7分

voidstrcpy(char*strDest,constchar*strSrc)

{

 //对源地址和目的地址加非0断言,加3分

 assert((strDest!

=NULL)&&(strSrc!

=NULL));

 while((*strDest++=*strSrc++)!

='’);

}

 

  10分

//为了实现链式操作,将目的地址返回,加3分!

char*strcpy(char*strDest,constchar*strSrc)

{

 assert((strDest!

=NULL)&&(strSrc!

=NULL));

 char*address=strDest;

 while((*strDest++=*strSrc++)!

='’);

  returnaddress;

}

  从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!

需要多么扎实的基本功才能写一个完美的strcpy啊!

再看看下面的一段程序有什么错误:

swap(int*p1,int*p2)

{

 int*p;

 *p=*p1;

 *p1=*p2;

 *p2=*p;

}

  在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。

在VC++中DEBUG运行时提示错误“AccessViolation”。

该程序应该改为:

swap(int*p1,int*p2)

{

 intp;

 p=*p1;

 *p1=*p2;

 *p2=p;

}

试题3:

写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

另外,当你写下面的代码时会发生什么事?

least=MIN(*p++,b);

  解答:

#defineMIN(A,B)((A)<=(B)?

(A):

(B))

  MIN(*p++,b)会产生宏的副作用

  剖析:

  这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。

  程序员对宏定义的使用要非常小心,特别要注意两个问题:

  

(1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。

所以,严格地讲,下述解答:

#defineMIN(A,B)(A)<=(B)?

(A):

(B)

#defineMIN(A,B)(A<=B?

A:

B)

  都应判0分;

  

(2)防止宏的副作用。

  宏定义#defineMIN(A,B)((A)<=(B)?

(A):

(B))对MIN(*p++,b)的作用结果是:

((*p++)<=(b)?

(*p++):

(*p++))

  这个表达式会产生副作用,指针p会作三次++自增操作。

  除此之外,另一个应该判0分的解答是:

#defineMIN(A,B)((A)<=(B)?

(A):

(B));

  这个解答在宏定义的后面加“;”,显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。

试题5:

编写一个函数,作用是把一个char组成的字符串循环右移n个。

比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”

  函数头是这样的:

//pStr是指向以''结尾的字符串的指针

//steps是要求移动的n

voidLoopMove(char*pStr,intsteps)

{

 //请填充...

}

  解答:

  正确解答1:

voidLoopMove(char*pStr,intsteps)

{

 intn=strlen(pStr)-steps;

 chartmp[MAX_LEN];

 strcpy(tmp,pStr+n);

 strcpy(tmp+steps,pStr);

 *(tmp+strlen(pStr))='';

 strcpy(pStr,tmp);

}

  正确解答2:

voidLoopMove(char*pStr,intsteps)

{

 intn=strlen(pStr)-steps;

 chartmp[MAX_LEN];

 memcpy(tmp,pStr+n,steps);

 memcpy(pStr+steps,pStr,n);

 memcpy(pStr,tmp,steps);

}

  剖析:

  这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。

  最频繁被使用的库函数包括:

  

(1)strcpy

  

(2)memcpy

(3)memset

FuYu注释:

这两种方法都很业余,都是算法能力差的人给出的答案,都要用chartmp[MAX_LEN]这么多辅助空间,“MAX_LEN”是多么好笑的用法。

标准答案是对倒、对倒、再对倒。

试题1:

请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1

  解答:

intcheckCPU()

{

 {

  unionw

  {

   inta;

   charb;

  }c;

  c.a=1;

  retu

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1