12.请完成以下题目。注意,请勿直接调用 ANSI C 函数库中的函数实现。
a)请编写一个 C 函数,该函数给出一个字节中被置 1 的位的个数,并请给出该题的至少一个不同解法。
第一种unsigned int TestAsOne0(char log)
{
int i;
unsigned int num=0, val;
for(i=0; i<8; i++)
{
val = log >> i; //移位
val &= 0x01; //与1相与
if(val)
num++;
}
return num;
}
第二种unsigned int TestAsOne1(char log)
{
int i;
unsigned int num=0, val;
for(i=0; i<8; i++)
{
val = (~log) >> i; //反码?
val &= 0x00; //与0相与
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+1;
}
return num;
}
c)请编写一个 C 函数,该函数将给定的一个整数转换成字符串。
void IntToCharChange(int num, char* pval)
{
char strval[100];
int i, j;
int val0 = 0;
int val1 = 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 函数,该函数将一个字符串逆序。
void AntitoneValue(char* father, char* child)
{
int i;
char source[100];
int j = 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 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。
int search(char *cpSource, int n, char ch) //起始地址,搜索长度,目标字符
{
int i;
for(i=0; i<n && *(cpSource+i) != ch; ++i);
return i;
}
f)请编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的。
int ChildString(char*p) //自己写
{
Char *q=p;
int stringlen=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++;
}
}
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.area() == 150);
}
14.假设现有一个单向的链表,但是只知道只有一个指向该节点的指针p,并且假设这个节
点不是尾节点,试编程实现删除此节点
参考:将下一个节点的内容复制到本节点上,然后删除下一个节点;
15.写一个程序,把一个100以内的自然数分解因数。(自然数分解因数就是将一个自然数
分解为几个素数的乘积,提示,由于该数不是很大,所以可以将质数保存在数组中,以加快计
算速度)
16.编写一个Identify的分配、释放的函数,为1-10000之间的自然数。
17.分别实现itoa和atoi.
#include<stdio.h> |
(2)itoa的实现:
#include<stdio.h> |
18.Consider the following code:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int i = 1;
char buf[4];
strcpy(buf, "AAAA");
printf("%d\n", 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=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;
int i,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.有双向循环链表结点:(华为面试题)
typedef struct node
{
int date;
struct node *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> ?
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=1;
pb->front->next=pb->next;
pb->next->front=pb->front;
bhead=bhead->next;
pbb=pb;
pb=pb->next;
delete pbb;
}
else
{
boy=1;
pb->front->next=pb->next;
pb->next->front=pb->front;
pbb=pb;
pb=pb->next;
delete pbb;
}
}
else
pb=pb->next;
}
while(paa->next!=ahead && boy==1)
{
if(paa->date==boys)
{
cout<<"delete A:"<<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;
delete paaa;
}
else
{
paa->front->next=paa->next;
paa->next->front=paa->front;
paaa=paa;
paa=paa->next;
delete paaa;
}
}
else
{
paa=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=1;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=1;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;
}
void main()
{
printf("%s", GetStr());
}
会输出123吗?123创建在堆上还是栈上呢?123的空间是什么时候释放的?
参考:"123" 是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈 在程序结束时自动释放