在第一版中,我将通讯录可以保存的人的数量设置为定长,这样具有很大的缺陷,那就是当通讯录满的时候没有办法再增加人的信息,或许会有人说,那我再修改数组的大小就好了,但是你要修改为多少才会合适呢?有人说我把数组的大小扩大为原来的两倍,这样是可以存储更多的信息,但是如果我只需要再增加一个人的信息,那给数组开辟的空间不是就会浪费掉吗?
所以才会有第二版的动态增长型的通讯录,这样你需要多少空间,就在堆区申请多大的空间,当申请的空间不够用时,我还可以使用realloc函数来进行扩容,直到不能申请为止。但是,应该注意的是:在堆区开辟的空间必须由程序员自己释放,否则会产生内存泄漏。
#pragma once
#pragma warning (disable :4996)
#define MAX_PEOPLES 100
#define MAX_NAME 20
#define MAX_ADDRESS 50
#define INCREMENT 50
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<malloc.h>
typedef struct
{
char name[MAX_NAME];
unsigned char age;
char sex[10];
char telephone[12];
char address[MAX_ADDRESS];
}People_t;
typedef struct peo
{
People_t *per_mesg;
int count;//实际的人数
int length;
}seqlist,*pseqlist;
enum select{Quit,Add,Delect,Find,Modify,Print,Clear,Sort,};
void menu();
void add_peo(pseqlist* message);
void print_people_message(pseqlist* message);
static int find_peo_sub(pseqlist* message,char *name);
void delete_peo_message(pseqlist* message);
void find(pseqlist* message);
void modify(pseqlist* message);
void clearall(seqlist * message);
void sort(pseqlist* message);
void Init_seqlist(pseqlist* message);
void DestoryContact(pseqlist c);
#include"contact.h"
void menu()
{
printf("###########################\n");
printf("#1.add############2.delete#\n");
printf("#3.find###########4.modiyf#\n");
printf("#5.print###########6.clear#\n");
printf("#7.sort###########0.quit##\n");
printf("###########################\n");
}
//初始化顺序表
void Init_seqlist(pseqlist* message)
{
(*message) = (pseqlist)malloc(sizeof(seqlist));
if (NULL == (*message))
{
printf("out of memory\n");
exit(1);
}
(*message)->per_mesg = (People_t *)malloc(sizeof(People_t) * MAX_PEOPLES);
(*message)->length = MAX_PEOPLES;
(*message)->count = 0;
if (NULL == (*message)->per_mesg)
{
printf("out of memory\n");
exit(1);
}
printf("初始化成功\n");
}
//添加人员的信息
void add_peo(pseqlist* message)
{
if ((*message)->count >= (*message)->length)
{
People_t * newbase = (People_t *)realloc((*message)->per_mesg,
(MAX_PEOPLES + INCREMENT) * sizeof(People_t) * INCREMENT);
if (NULL ==newbase )
{
printf("out of memory\n");
exit(1);
}
(*message)->per_mesg = newbase;
(*message)->length += INCREMENT;
}
else
{
printf("姓名:>");
scanf("%s",(*message)->per_mesg[(*message)->count].name);
printf("年龄:>");
scanf("%d",&(*message)->per_mesg[(*message)->count].age);
printf("性别:>");
scanf("%s",(*message)->per_mesg[(*message)->count].sex);
printf("电话:>");
scanf("%s",(*message)->per_mesg[(*message)->count].telephone);
printf("地址:>");
scanf("%s",(*message)->per_mesg[(*message)->count].address);
(*message)->count++;
}
}
//打印通讯录中人员的信息
void print_people_message(pseqlist* message)
{
if ((*message)->count != 0)
{
for (int i = 0; i < (*message)->count; i++)
{
printf("name : %s ",(*message)->per_mesg[i].name );
printf("age : %d ",(*message)->per_mesg[i].age );
printf("sex : %s ",(*message)->per_mesg[i].sex);
printf("telephone : %s ",(*message)->per_mesg [i].telephone);
printf("address : %s ",(*message)->per_mesg [i].address);
printf("\n");
}
}
else
{
printf("通讯录为空\n");
}
}
//查找下标
static int find_peo_sub(pseqlist* message,char *name)
{
int i = 0;
for (i = 0; i < (*message)->count; i++)
{
if (strcmp(name,(*message)->per_mesg[i].name ) == 0)
{
return i;
}
}
return -1;
}
//删除通讯录中的人员信息
void delete_peo_message(pseqlist* message)
{
if ( (*message)->count <= 0)
{
printf("通讯录为空\n");
return ;
}
printf("请输入要删除的联系人姓名:>");
char name[10];
scanf("%s",name);
int ret = find_peo_sub(message,name);
if (ret != -1)
{
for (int j = ret; j < (*message)->count; j++)
{
(*message)->per_mesg[j] = (*message)->per_mesg[j+1];
}
printf("删除成功\n");
(*message)->count--;
return ;
}
else
{
printf("通讯录中没有要删除的联系人\n");
}
}
//按姓名查找人员信息
void find(pseqlist* message)
{
if ( (*message)->count <= 0)
{
printf("通讯录为空\n");
return ;
}
printf("请输入你要查找联系人的姓名:>");
char name[10];
scanf("%s",name);
int ret = find_peo_sub(message,name);
if (ret != -1)
{
printf("name : %s age: %d sex : %s telephone : %s address %s\n",
(*message)->per_mesg[ret].name,(*message)->per_mesg[ret].age,(*message)->per_mesg[ret].sex,
(*message)->per_mesg[ret].telephone,(*message)->per_mesg[ret].address);
}
else
{
printf("没有找到该联系人\n");
}
}
//按联系人姓名修改信息
void modify(pseqlist* message)
{
if ( (*message)->count <= 0)
{
printf("通讯录为空\n");
return ;
}
printf("请输入要修改联系人的姓名:>");
char name[10];
scanf("%s",name);
int ret = find_peo_sub(message,name);
if (ret != -1)
{
printf("请输入要修改后的名字:>");
scanf("%s",(*message)->per_mesg[ret].name);
printf("请输入修改后的年龄:>");
scanf("%d",&(*message)->per_mesg[ret].age);
printf("请输入修改后的性别:>");
scanf("%s",(*message)->per_mesg[ret].sex);
printf("请输入修改后的电话:>");
scanf("%s",(*message)->per_mesg[ret].telephone);
printf("请输入要修改后的地址:>");
scanf("%s",(*message)->per_mesg[ret].address);
printf("修改成功:\n");
}
else
{
printf("要修改的联系人不存在\n");
}
}
//清空通讯录
void clearall(seqlist * message)
{
message->count = 0;
}
//按姓名排序
void sort(pseqlist* message)
{
//冒泡排序
if ( (*message)->count <= 0)
{
printf("通讯录为空\n");
return ;
}
for (int i = 0; i < (*message)->count-1; i++)
{
int flag = 1;
for (int j = 0; j < (*message)->count-1-i; j++)
{
if (strcmp((*message)->per_mesg[j].name,(*message)->per_mesg[j+1].name) > 0)
{
flag = 0;
People_t tmp = (*message)->per_mesg[j];
(*message)->per_mesg[j] = (*message)->per_mesg[j+1];
(*message)->per_mesg[j+1] =tmp;
}
}
if (flag)
{
break;
}
}
}
void DestoryContact(pseqlist c)
{
assert(c);
free(c->per_mesg);
c->per_mesg = NULL;
free(c);
c = NULL;
}
#include"contact.h"
int main()
{
pseqlist pro;
Init_seqlist(&pro);
while (1)
{
menu();
printf("请选择:>");
int select = 0;
scanf("%d",&select);
switch(select)
{
case Quit:
DestoryContact(pro);
exit(EXIT_SUCCESS);
break;
case Add:
add_peo(&pro);
break;
case Delect:
delete_peo_message(&pro);
break;
case Find:
find(&pro);
break;
case Modify:
modify(&pro);
break;
case Print:
print_people_message(&pro);
break;
case Clear:
clearall(pro);
break;
case Sort:
sort(&pro);
break;
default :
break;
}
}
system("pause");
return 0;
}