模拟实现通讯录-静态的方法:
题目描述:
实现一个通讯录:通讯录可以用于存储1000个人的信息:每个人的信息包括:姓名,性别,年龄,电话,住址
提供的方法:
1.添加联系人信息
2.删除指定联系人信息
3.查找指定联系人信息
4.修改指定联系人信息
5.显示所有联系人信息
6.清空联系人信息
7.以名字排序所有联系人
模拟实现通讯录-动态的方法:
【题目分析】:
要理解动态实现通讯录首先必须了解动态内存开辟的几个常见的函数,在我们的代码实现过程中我们用到了
free,malloc,realloc
这几个动态内存开辟的函数,下面我们就来介绍这几个函数的功能以及如何使用:
malloc
:打开MSDN我们发现malloc它的函数原型为:
void *malloc(size_t size)
,size它是你要分配的字节数,而malloc它的返回值类型是void *,所以一般情况下我们都把分配好的空间强制类型转化成你要使用的类型,用malloc分配的空间要判断是否为空的情况,下面提供一种判断空的方法:
char *p=(char *)malloc(10*sizeof(char));
if(p == NULL)
{
printf("out of menory");
exit(EXIT_FAILURE);
}
free:
它的函数原型为:
void free(void *memblock),
free一般和malloc配套使用,用于释放堆上的空间;
realloc:
它的函数原型为:
void *realloc(void *memblock,size_t size),
realloc函数用于修改一个原本已经分配的内存块的大小,使用这个函数,你可以使一块内存扩大或者缩小;realloc使内存扩大,那仫这块内存的内容依然保留,新增加的内容添加到原先内存块的后面,在实现通讯录的添加联系人功能时,我们设置的初始容量是2,那仫是不是就不可以继续添加了呢?此时我们的realloc就闪亮登场了,我们知道realloc有一个功能就是用于扩容这不就解决了增容的问题了吗?实现如下:
void Add(Pcon pcon) //添加联系人
{
if(pcon->size >= pcon->capacity)
{
PerInfo *tmp=(PerInfo *)realloc(pcon->data,(pcon->capacity+MAX_RISE)*sizeof(PerInfo));
//当实际联系人个数和初始化的容量相等时用realloc增容
if(tmp == NULL)
{
printf("out of menory\n");
exit(EXIT_FAILURE);
}
else
{
pcon->data=tmp;
pcon->capacity+=MAX_RISE;
}
}
printf("请输入你添加之后的联系人信息:(姓名 年龄 性别 联系电话 住址):\n");
scanf("%s",pcon->data[pcon->size].name);
scanf("%d",&(pcon->data[pcon->size].age));
scanf("%s",pcon->data[pcon->size].sex);
scanf("%s",pcon->data[pcon->size].tele);
scanf("%s",pcon->data[pcon->size].addr);
pcon->size++;
printf("添加成功\n");
}
realloc的另一个功能就是用于缩小一个内存块:此时该内存的尾部内存便会被拿掉,剩余部分内存原先的内容会依然保留;
如果realloc函数的第一个参数是NULL,那仫此时它的操作就和malloc一样
calloc:
它的函数原型为:
void *calloc(size_t num,size_t size)
,num:所需元素的数量,size:每个元素的字节数它的作用和malloc类似, calloc将分配好的内存初始化为0而malloc并没有将内存初始化为0 ,也就是说
calloc=malloc+memset
;
好了理解了这下常见的内存分配函数我们就来实现动态的通讯录吧!
在这里附上程序源代码便于读者理解:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NAME_MAXNUM 20
#define SEX_MAXNUM 5
#define TELE_MAXNUM 12
#define ADDR_MAXNUM 10
#define MAX 1000
#define MAX_INIT 2
#define MAX_RISE 2
enum OP
{
EXIT,
ADD,
DEL,
SEARCH,
REVISE,
DISPLAY,
EMPTY,
SORT
};
typedef struct PerInfo
{
char name[NAME_MAXNUM];
int age;
char sex[SEX_MAXNUM];
char tele[TELE_MAXNUM];
char addr[ADDR_MAXNUM];
}PerInfo;
typedef struct Contact
{
PerInfo *data; //存储所有联系人的所有信息
int size; //记录联系人的个数
int capacity; //通讯录的容量
}Contact,*Pcon;
void init(Pcon pcon)
{
//memset(pcon->data,0,MAX*sizeof(PerInfo));
//pcon->size=0;
pcon->data=(PerInfo *)malloc(MAX_INIT*sizeof(PerInfo));
if(pcon->data == NULL)
{
printf("out of menory");
exit(EXIT_FAILURE);
}
pcon->size=0;
pcon->capacity=MAX_INIT;
}
void menu()
{
printf("***************简易通讯录***************\n");
printf("****1.添加联系人*******2.删除联系人****\n");
printf("****3.查找联系人*******4.修改联系人****\n");
printf("****5.显示联系人*******6.清空联系人****\n");
printf("****7.以名字排序联系人*0.退出**********\n");
printf("***************************************\n");
}
void Add(Pcon pcon) //添加联系人
{
if(pcon->size >= pcon->capacity)
{
PerInfo *tmp=(PerInfo *)realloc(pcon->data,(pcon->capacity+MAX_RISE)*sizeof(PerInfo));
//当实际联系人个数和初始化的容量相等时用realloc增容
if(tmp == NULL)
{
printf("out of menory\n");
exit(EXIT_FAILURE);
}
else
{
pcon->data=tmp;
pcon->capacity+=MAX_RISE;
}
}
printf("请输入你添加之后的联系人信息:(姓名 年龄 性别 联系电话 住址):\n");
scanf("%s",pcon->data[pcon->size].name);
scanf("%d",&(pcon->data[pcon->size].age));
scanf("%s",pcon->data[pcon->size].sex);
scanf("%s",pcon->data[pcon->size].tele);
scanf("%s",pcon->data[pcon->size].addr);
pcon->size++;
printf("添加成功\n");
}
int Find_position(Pcon pcon,char *str) //查找联系人函数
{
int i=0;
for(i=0;i<pcon->size;i++)
{
if(strcmp(pcon->data[i].name,str) == 0) //将要查找的姓名与通讯录里的联系人匹配,找到就返回下标
{
return i;
}
}
return -1;
}
void Del(Pcon pcon) //删除指定联系人
{
int ret=0;
int i=0;
char str[NAME_MAXNUM]={0};
printf("请输入你要删除的联系人姓名:");
scanf("%s",str);
ret=Find_position(pcon,str);
if(ret != -1)
{
for(i=ret;i<pcon->size;i++)
{
pcon->data[i]=pcon->data[i+1]; //删除的元素之后的元素往前挪一个位置
}
pcon->size--;
}
else
{
printf("通讯录里没有此联系人\n");
return ;
}
}
void Search(Pcon pcon) //查找指定联系人
{
int ret=0;
char str[NAME_MAXNUM]={0};
printf("请输入你要查找的联系人的名字:");
scanf("%s",str);
ret=Find_position(pcon,str);
if(ret != -1)
{
printf("查找成功\n");
}
else
{
printf("通讯录里无此人\n");
return ;
}
}
void Revise(Pcon pcon) //修改指定联系人
{
int ret=0;
char str[NAME_MAXNUM]={0};
printf("请输入你要修改的联系人的姓名:");
scanf("%s",str);
ret=Find_position(pcon,str);
if(ret != -1)
{
int input=0;
printf("请输入你要修改的信息:1.姓名2.年龄3.性别4.联系电话5.住址\n");
scanf("%d",&input);
switch(input)
{
case 1:printf("请输入修改后的名字:\n");
scanf("%s",pcon->data[ret].name);break;
case 2:printf("请输入修改后的年龄:\n");
scanf("%d",&(pcon->data[ret].age));break;
case 3:printf("请输入修改后的性别:\n");
scanf("%s",pcon->data[ret].sex);break;
case 4:printf("请输入修改后的联系电话:\n");
scanf("%s",pcon->data[ret].tele);break;
case 5:printf("请输入修改后的住址:\n");
scanf("%s",pcon->data[ret].addr);break;
default:printf("error");
break;
}
}
else
{
printf("通讯录里无此人\n");
return ;
}
}
void Display(Pcon pcon) //显示联系人信息
{
int i=0;
for(i=0;i<pcon->size;i++)
{
printf("%s %d %s %s %s\n",pcon->data[i].name,pcon->data[i].age,pcon->data[i].sex,\
pcon->data[i].tele,pcon->data[i].addr);
}
}
void Empty(Pcon pcon) //清空联系人
{
pcon->size=0;
}
void Sort_name(Pcon pcon) //以名字排序联系人
{
int flag=0;
int i=0;
int j=0;
for(i=0;i<pcon->size-1;i++)
{
flag=0; //对冒泡排序的优化
for(j=0;j<pcon->size-1-i;j++)
{
if(strcmp(pcon->data[j].name,pcon->data[j+1].name) > 0) //默认升序排列
{
PerInfo tmp=pcon->data[j];
pcon->data[j]=pcon->data[j+1];
pcon->data[j+1]=tmp;
flag=1;
}
}
if(flag == 0)
break;
}
}
void Free(Pcon pcon)
{
free(pcon->data);
pcon->data=NULL;
exit(0);
}
int main()
{
Contact pcon;
int intput=1;
init(&pcon);
while(intput)
{
menu();
printf("请输入一个你要选择的操作:");
scanf("%d",&intput);
if(intput >= 0 && intput <= 7)
{
switch(intput)
{
case ADD:Add(&pcon);
break;
case DEL:Del(&pcon);
break;
case SEARCH:Search(&pcon);
break;
case REVISE:Revise(&pcon);
break;
case DISPLAY:Display(&pcon);
break;
case EMPTY:Empty(&pcon);
break;
case SORT:Sort_name(&pcon);
break;
case EXIT:Free(&pcon);
break;
}
}
}
system("pause");
return 0;
}
在这里以一句话勉励自己:敢于尝试才可能成功,加油!