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的分配、释放的函数,为1-10000之间的自然数。
17.分别实现itoa和atoi.
#include<stdio.h> |
(2)itoa的实现:
#include<stdio.h> |
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越界,用0把buf开始的第4(0开始)个字节覆盖掉了.而x86是LSB排列顺序,所以真好覆盖了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;
有两个双向循环链表A,B,知道其头指针为: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"是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈在程序结束时自动释放