CC++语言程序设计笔试面试题19文档格式.docx

上传人:b****6 文档编号:16215737 上传时间:2022-11-21 格式:DOCX 页数:14 大小:21.50KB
下载 相关 举报
CC++语言程序设计笔试面试题19文档格式.docx_第1页
第1页 / 共14页
CC++语言程序设计笔试面试题19文档格式.docx_第2页
第2页 / 共14页
CC++语言程序设计笔试面试题19文档格式.docx_第3页
第3页 / 共14页
CC++语言程序设计笔试面试题19文档格式.docx_第4页
第4页 / 共14页
CC++语言程序设计笔试面试题19文档格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

CC++语言程序设计笔试面试题19文档格式.docx

《CC++语言程序设计笔试面试题19文档格式.docx》由会员分享,可在线阅读,更多相关《CC++语言程序设计笔试面试题19文档格式.docx(14页珍藏版)》请在冰豆网上搜索。

CC++语言程序设计笔试面试题19文档格式.docx

因为x+2y+5z=100

所以x+2y=100-5z,且z<

=20x<

=100y<

=50

所以(x+2y)<

=100,且(x+5z)是偶数

对z作循环,求x的可能值如下:

z=0,x=100,98,96,...0

z=1,x=95,93,...,1

z=2,x=90,88,...,0

z=3,x=85,83,...,1

z=4,x=80,78,...,0

......

z=19,x=5,3,1

z=20,x=0

因此,组合总数为100以内的偶数+95以内的奇数+90以内的偶数+...+5以内的奇数+1,

即为:

(51+48)+(46+43)+(41+38)+(36+33)+(31+28)+(26+23)+(21+18)+(16+13)+(11+8)+(6+3)+1

某个偶数m以内的偶数个数(包括0)可以表示为m/2+1=(m+2)/2

某个奇数m以内的奇数个数也可以表示为(m+2)/2

所以,求总的组合次数可以编程为:

for(intm=0;

m<

m+=5)

{

number+=(m+2)/2;

}

这个程序,只需要循环21次,两个变量,就可以得到答案,比上面的那个程序高效了许多

倍----只是因为作了一些简单的数学分析

这再一次证明了:

计算机程序=数据结构+算法,而且算法是程序的灵魂,对任何工程问

题,当用软件来实现时,必须选取满足当前的资源限制,用户需求限制,开发时间限制等种

种限制条件下的最优算法。

而绝不能一拿到手,就立刻用最容易想到的算法编出一个程序了

事——这不是一个专业的研发人员的行为。

那么,那种最容易想到的算法就完全没有用吗?

不,这种算法正好可以用来验证新算法

的正确性,在调试阶段,这非常有用。

在很多大公司,例如微软,都采用了这种方法:

在调

试阶段,对一些重要的需要好的算法来实现的程序,而这种好的算法又比较复杂时,同时用

容易想到的算法来验证这段程序,如果两种算法得出的结果不一致(而最容易想到的算法保

证是正确的),那么说明优化的算法出了问题,需要修改。

可以举例表示为:

#ifdefDEBUG

intsimple();

#endif

intoptimize();

inafunction:

result=optimize();

ASSERT(result==simple());

这样,在调试阶段,如果简单算法和优化算法的结果不一致,就会打出断言。

同时,在程

序的发布版本,却不会包含笨重的simple()函数。

——任何大型工程软件都需要预先设计良

好的调试手段,而这里提到的就是一种有用的方法。

一个学生的信息是:

姓名,学号,性别,年龄等信息,用一个链表,把这些学生信息连在一起,给出一个age,

在些链表中删除学生年龄等

于age的学生信息。

#include"

stdio.h"

conio.h"

structstu{

charname[20];

charsex;

intno;

intage;

structstu*next;

}*linklist;

structstu*creatlist(intn)

inti;

//h为头结点,p为前一结点,s为当前结点

structstu*h,*p,*s;

h=(structstu*)malloc(sizeof(structstu));

h->

next=NULL;

p=h;

for(i=0;

i<

n;

i++)

{

s=(structstu*)malloc(sizeof(structstu));

p->

next=s;

printf("

Pleaseinputtheinformationofthestudent:

namesexnoage\n"

);

scanf("

%s%c%d%d"

s->

name,&

s->

sex,&

no,&

age);

p=s;

Createsuccessful!

return(h);

voiddeletelist(structstu*s,inta)

structstu*p;

while(s->

age!

=a)

s=s->

next;

if(s==NULL)

Therecordisnotexist."

else

next=s->

Deletesuccessful!

voiddisplay(structstu*s)

while(s!

=NULL)

%s%c%d%d\n"

name,s->

sex,s->

no,s->

intmain()

structstu*s;

intn,age;

Pleaseinputthelengthofseqlist:

\n"

%d"

&

n);

s=creatlist(n);

display(s);

Pleaseinputtheage:

deletelist(s,age);

return0;

2、实现一个函数,把一个字符串中的字符从小写转为大写。

voiduppers(char*s,char*us)

for(;

*s!

='

\0'

;

s++,us++)

if(*s>

a'

&

*s<

z'

*us=*s-32;

*us=*s;

*us='

char*s,*us;

charss[20];

Pleaseinputastring:

%s"

ss);

s=ss;

uppers(s,us);

Theresultis:

\n%s\n"

us);

getch();

随机输入一个数,判断它是不是对称数(回文数)(如3,121,12321,45254)。

不能用字符串库函数

/***************************************************************

1.

函数名称:

Symmetry

功能:

判断一个数时候为回文数(121,35653)

输入:

长整型的数

输出:

若为回文数返回值为1esle0

******************************************************************/

unsignedcharSymmetry(longn)

longi,temp;

i=n;

temp=0;

while(i)//不用出现长度问题,将数按高低位掉换

temp=temp*10+i%10;

i/=10;

return(temp==n);

}

方法一

/*---------------------------------------------------------------------------

判断字符串是否为回文数字

实现:

先将字符串转换为正整数,再将正整数逆序组合为新的正整数,两数相同则为回文数字

char*s:

待判断的字符串

返回:

0:

正确;

1:

待判断的字符串为空;

2:

待判断的字符串不为数字;

3:

字符串不为回文数字;

4:

待判断的字符串溢出

----------------------------------------------------------------------------*/

unsignedIsSymmetry(char*s)

char*p=s;

longnNumber=0;

longn=0;

longnTemp=0;

/*判断输入是否为空*/

if(*s==\'

\\0\'

return1;

/*将字符串转换为正整数*/

while(*p!

=\'

/*判断字符是否为数字*/

if(*p<

\'

0\'

||*p>

9\'

return2;

/*判断正整数是否溢出*/

if((*p-\'

)>

(4294967295-(nNumber*10)))

return4;

nNumber=(*p-\'

)+(nNumber*10);

p++;

/*将数字逆序组合,直接抄楼上高手的代码,莫怪,呵呵*/

n=nNumber;

while(n)

if((n%10)>

(4294967295-(nTemp*10)))

return3;

nTemp=nTemp*10+n%10;

n/=10;

/*比较逆序数和原序数是否相等*/

if(nNumber!

=nTemp)

方法二

先得到字符串的长度,再依次比较字符串的对应位字符是否相同

字符串不为回文数字

unsignedIsSymmetry_2(char*s)

intnLen=0;

inti=0;

/*得到字符串长度*/

nLen++;

/*长度不为奇数,不为回文数字*/

if(nLen%2==0)

/*长度为1,即为回文数字*/

if(nLen==1)

/*依次比较对应字符是否相同*/

i=nLen/2-1;

while(i)

if(*(p+i)!

=*(p+nLen-i-1))

i--;

求2~2000的所有素数.有足够的内存,要求尽量快

intfindvalue[2000]={2};

staticintfind=1;

booladjust(intvalue)

assert(value>

=2);

if(value==2)returntrue;

for(inti=0;

=find;

if(value%findvalue[i]==0)

returnfalse;

findvalue[find++];

returntrue;

1.引言  本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。

文中

的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。

  许多面试题看似简单,却需要深厚的基

本功才能给出完美的解答。

企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样

的程度,我们能真正写好一个strcpy函数吗?

我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中

的2分。

读者可从本文看到strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次。

此外,还有一些面

试题考查面试者敏捷的思维能力。

  分析这些面试题,本身包含很强的趣味性;

而作为一名研发人员,通过对

这些面试题的深入剖析则可进一步增强自身的内功。

  2.找错题  试题1:

voidtest1(){ charstring

[10];

 char*str1="

0123456789"

 strcpy(string,str1);

}  试题2:

voidtest2(){ charstring

[10],str1[10];

 inti;

 for(i=0;

i<

10;

i++) {  str1[i]='

 } strcpy(string,str1);

}  

试题3:

voidtest3(char*str1){ 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(char*strDest,

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

='

\0’);

}  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++=*

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

char*strcpy(char

*strDest,constchar*strSrc){ assert((strDest!

 char*address=

strDest;

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

  returnaddress;

}  从2分到10分的几个

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

需要多么扎实的基本功才能写一

个完美的strcpy啊!

  (4)对strlen的掌握,它没有包括字符串末尾的'

  读者看了不同分值的strcpy版

本,应该也可以写出一个10分的strlen函数了,完美的版本为:

intstrlen(constchar*str)//输入参数

const{ assert(strt!

=NULL);

//断言字符串地址非0 intlen;

 while((*str++)!

) {  

len++;

 } returnlen;

}  试题4:

voidGetMemory(char*p){ p=(char*)malloc(100);

}void

Test(void){ char*str=NULL;

 GetMemory(str);

 strcpy(str,"

helloworld"

);

 printf(str

}  试题5:

char*GetMemory(void){ charp[]="

 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"

}  试题7:

voidTest(void){ char*str=(char

*)malloc(100);

 free(str);

 ...//省略的其它语句}  解答:

  试题

4传入中GetMemory(char*p)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,

执行完char*str=NULL;

GetMemory(str);

  后的str仍然为NULL;

  试题5中charp[]="

hello

world"

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函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。

在VC++中DEBUG运行时提示错

误“AccessViolation”。

该程序应该改为:

swap(int*p1,int*p2){ intp;

 p=*p1;

 *p2

=p;

 

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

当前位置:首页 > PPT模板 > 中国风

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

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