C++笔试和面试题

12.请完成以下题目。注意,请勿直接调用ANSIC函数库中的函数实现。

a)请编写一个C函数,该函数给出一个字节中被置1的位的个数,并请给出该题的至少一个不同解法。

第一种unsignedintTestAsOne0(charlog)
{
inti;
unsignedintnum=0,val;
for(i=0;i<8;i++)
{
val=log>>i;//移位
val&=0x01;//1相与
if(val)
num++;
}
returnnum;
}

第二种unsignedintTestAsOne1(charlog)
{
inti;
unsignedintnum=0,val;
for(i=0;i<8;i++)
{
val=(~log)>>i;//反码?
val&=0x00;//0相与
if(!val)
num++;
}
returnnum;
}

b)请编写一个C函数,该函数将给定的一个字符串转换成整数。

intInvert(char*str)

{

intnum=0;

while(*str!='\0')

{

intdigital=*str-48;

num=num*10+digital;

str=str+1;

}

returnnum;

}

c)请编写一个C函数,该函数将给定的一个整数转换成字符串。

voidIntToCharChange(intnum,char*pval)
{
charstrval[100];
inti,j;
intval0=0;
intval1=0;

val0=num;
for(i=0;i<100;i++)
{
val1=val0%10;//取余
val0=val0/10;//取整
strval[i]=val1+48;//数字字符
if(val0<10)
{
i++;
strval[i]=val0+48;
break;
}
}
for(j=0;j<=i;j++)//倒置
{
pval[j]=strval[i-j];
}
pval[j]='\0';
}

d)请编写一个C函数,该函数将一个字符串逆序。

voidAntitoneValue(char*father,char*child)
{
inti;
charsource[100];
intj=0;

while(father[j])//放入source[j]为长度
{
source[j]=father[j];
j++;
if(j>99)
{
return;
}
}
source[j]='\0';

for(i=0;i<j;i++)
{
child[i]=source[j-i-1];//反序
}
child[i]='\0';
}

e)请编写一个C函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。

intsearch(char*cpSource,intn,charch)//起始地址,搜索长度,目标字符
{
inti;
for(i=0;i<n&&*(cpSource+i)!=ch;++i);
returni;
}

f)请编写一个C函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的。

intChildString(char*p)//自己写

{

Char*q=p;

intstringlen=0,i=0,j=1,len=0,maxlen=1;

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+1;

len=0;

}

else{

len=0;

}

i++;

j++;

}

}

returnmaxlen;

}

给出演示上述函数功能的一个简单程序,并请编写对应的Makefile文件

13.我们需要编写一个图形相关的应用程序,需要处理大量图形(Shape)信息,图形有矩形(Rectangle),正方形(Square),圆形(Circle)等种类,应用需要计算这些图形的面积,并且可能需要在某个设备上进行显示(使用在标准输出上打印信息的方式做为示意)

a)请用面向对象的方法对以上应用进行设计,编写可能需要的类

b)请给出实现以上应用功能的示例性代码,从某处获取图形信息,

并且进行计算和绘制

c)如果你的Square继承自Rectangle,请给出理由,如果不是,

请给出理由,并且请比较两种方式的优劣

d)请问你所编写的类,在如下代码中会有何表现,请解释

voidtest_rectangle_area(Rectangle&r)

{

r.set_width(10);

r.set_height(15);

assert(r.area()==150);

}

14.假设现有一个单向的链表,但是只知道只有一个指向该节点的指针p,并且假设这个节

点不是尾节点,试编程实现删除此节点

参考:将下一个节点的内容复制到本节点上,然后删除下一个节点;

15.写一个程序,把一个100以内的自然数分解因数。(自然数分解因数就是将一个自然数

分解为几个素数的乘积,提示,由于该数不是很大,所以可以将质数保存在数组中,以加快计

算速度)

16.编写一个Identify的分配、释放的函数,为110000之间的自然数。

17.分别实现itoaatoi.

#include<stdio.h>
intatoi(constchar*str)
{
intvalue=0;
boolb_plus=true;//判断符号

switch(*str)//过滤符号

{
case'+':
str++;
break;
case'-':
b_plus=false;
str++;
break;
default:
break;
}

while('\0'!=*str)
{
value=(value*10)+(*str-'0');
str++;
}
if(!b_plus)
value=-value;
returnvalue;
}

voidmain()
{
charstr[]="-999";
intvalue=atoi(str);
printf("Theresultis:%d\n",value);
}

(2)itoa的实现:

#include<stdio.h>
voiditoa(intvalue,char*str)
{
if(value<0)//如果是负数,str[0]='-',并把value取反(变成正整数)

{
str[0]='-';
value=0-value;
}
inti,j;
for(i=1;value>0;i++,value/=10)//value[1]开始存放value的数字字符,不过是逆序,等下再反序过来

str[i]=value%10+'0';//将数字加上0ASCII('0')就得到该数字的ASCII

for(j=i-1,i=1;j-i>=1;j--,i++)//将数字字符反序存放

{
str[i]=str[i]^str[j];
str[j]=str[i]^str[j];
str[i]=str[i]^str[j];
}
if(str[0]!='-')//如果不是负数,则需要把数字字符下标左移一位,即减1

{
for(i=0;str[i+1]!='\0';i++)
str[i]=str[i+1];
str[i]='\0';
}
}

voidmain()
{
intvalue=-1212345;
charstr[10]={'\0'};//记得把str全填充为'\0'

itoa(value,str);
printf("Theresultis:%s\n",str);
}

18.Considerthefollowingcode:

#include<stdio.h>

#include<string.h>

intmain(intargc,char*argv[]){

inti=1;

charbuf[4];

strcpy(buf,"AAAA");

printf("%d\n",i);

return0;

}

a)Whencompiledandexecutedonx86,whydoesthisprogramusuallynotoutputwhattheprogrammerintended?x86上为什么不能得到预期结果

b)NameseveralwaysinwhichthesecurityproblemthatcausesthisprogramnottooutputwhattheprogrammerintendedcanbepreventedWITHOUTchangingthecode.

参考:第一个问题:
32位情况:
x86,栈方向向上生长.main的栈中,先分配i空间(4byte),然后分配4个字节的buf(地址在i的上面,i).strcpy越界,0buf开始的第4(0开始)个字节覆盖掉了.x86LSB排列顺序,所以真好覆盖了i的内个数字1.所以显示出数字0.
16位情况同样分析即可.

2问?

19.intw=1,x=2,y=3,z=4;

m=(w<x)?w:x;

m=(m<y)?m:y;

m=(m<2)?m:z;

printf("m=%d",m);说出结果

答案:1

20.说出结果???

#include<stdio.h>

main()

{

FILE*fp;

inti,a[4]={1,2,3,4},b;

fp=fopen("data.dat","wb");//这里帮忙解释一下

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

fwrite(&a[i],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=%d\n",b);

}

21.有双向循环链表结点:(华为面试题)

typedefstructnode

{

intdate;

structnode*front,*next;

}_Node;

有两个双向循环链表AB,知道其头指针为:pHeadA,pHeadB,请写一函数将两上链表中date值相同的结点删除

参考算法:
1.取出A的一个元素d
2.收集B中有相同元素d的结点到垃圾箱,并从B里删除
3.收集A中有相同元素d的结点到垃圾箱,并从A里删除
4.删除垃圾箱中的所有元素
5.A链的指针指向下一个
6.重复1~5,直到A链循环到头了
注意的是第3步,在2步执行后垃圾箱不为空时才执行。

上述算法还可以做一点点优化:
1.加入两个变量cA,cB,分别记录当前A中和B中的元素个数
每次从较长者中取出一个元素来,先从较小者中找起
若没有,则不必在较长者中浪费时间了

#include<iostream.h>
structNODE
{
intdate;
NODE*front,*next;
};

voidredel(NODE*&ahead,NODE*&bhead)
{
intboy=0;
NODE*pa=ahead,*pb=bhead,*paa,*paaa,*paaaa,*pbb;
while(pa->next!=ahead)
{
intboys=pa->date;//pa中一个值
paaaa=pa;
paa=pa;
pb=bhead;
while(pb->next!=bhead)
{
if(boys==pb->date)//如果pa,pb中有值相同
{
cout<<endl;
cout<<"deleteB:"<<paa->date<<"";
if(pb==bhead)
{
boy=1;
pb->front->next=pb->next;
pb->next->front=pb->front;
bhead=bhead->next;
pbb=pb;
pb=pb->next;
deletepbb;
}
else
{
boy=1;
pb->front->next=pb->next;
pb->next->front=pb->front;
pbb=pb;
pb=pb->next;
deletepbb;
}
}
else
pb=pb->next;
}
while(paa->next!=ahead&&boy==1)
{
if(paa->date==boys)
{
cout<<"deleteA:"<<paa->date<<"";
if(paa==pa)
{
pa=pa->next;
ahead=pa;
paa->front->next=paa->next;
paa->next->front=paa->front;
paaa=paa;
paa=paa->next;
deletepaaa;
}
else
{
paa->front->next=paa->next;
paa->next->front=paa->front;
paaa=paa;
paa=paa->next;
deletepaaa;
}
}
else
{
paa=paa->next;
}
}
boy=0;
if(paaaa==pa)
pa=pa->next;
}
cout<<endl;
}

intmain()
{
NODE*A,*pHeadA,*B,*pHeadB;
A=newNODE;
B=newNODE;
pHeadA=A;
pHeadB=B;
for(inti=1;i<21;++i)//生成链表A,并赋初值!
{
A->date=i;
A->next=newNODE;
A->next->front=A;
A=A->next;
}
A=A->front;
deleteA->next;
A->next=pHeadA;
pHeadA->front=A;

for(inti=1;i<33;i+=2)//生成链表B,并赋初值!
{
B->date=i;
B->next=newNODE;
B->next->front=B;
B=B->next;
}
B=B->front;
deleteB->next;
B->next=pHeadB;
pHeadB->front=B;

redel(pHeadA,pHeadB);//调用函数删除相同结点!
}

22.

char*GetStr()

{

char*tmp;

tmp="123"

returntmp;

}

voidmain()

{

printf("%s",GetStr());

}

会输出123吗?123创建在堆上还是栈上呢?123的空间是什么时候释放的?

参考:"123"是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈在程序结束时自动释放

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值