上一篇通讯录是静态版的,在结构体中直接定义了一个容量大小为1000的数组Dhb[],在这一篇则是通过用malloc和free函数实现动态内存分配和释放,并运用realloc函数实现原分配内存的扩大或缩小,从而比静态版的通讯录更加节省空间,更加灵活,不会浪费内存空间或存在内存不够的问题。
和静态版通讯录一样,分别定义三个文件,代码如下:
contact.h
#ifndef __CONTACT_H__ #define __CONTACT_H__ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #define MAX_NAME 20 #define MAX_SEX 5 #define MAX_TELE 12 #define MAX_ADDR 30 #define DEFAULT 5 //初始通讯录大小 #define INC_SZ 5 //每次增容大小 enum PEO { EXIT, ADD, DEL, SERCH, MOD, SHOW, EMPTY, SORT, }; typedef struct people { char name[MAX_NAME]; char sex[MAX_SEX]; int age; char tele[MAX_TELE]; char address[MAX_ADDR]; }Peo; typedef struct contact { Peo *Dhb; int count; //统计通讯录当前人数 int capacity;//通讯录容量大小 }Con,*pCon; void cheak_cap(pCon p); //检查通讯录当前容量大小 void init_peo(pCon p); //初始化通讯录 void add_peo(pCon p); //添加联系人信息 void del_peo(pCon p); //删除指定联系人信息 void serch_peo(pCon p); //查找指定联系人并输出其信息 void mod_peo(pCon p); //修改指定联系人信息 void show_peo(pCon p); //显示所有联系人信息 void empty_peo(pCon p); //清空所有联系人信息 void sort_peo(pCon p); //用名字排序所有联系人信息 void destory_Dhb(pCon p); //释放动态开辟的内存 #endif //__CONTACT_H__
#include "contact.h" void init_peo(pCon p) //初始化通讯录 { p->Dhb=(Peo *)malloc(DEFAULT*sizeof(Peo)); if(p->Dhb==NULL) { printf("out of memory\n"); exit(EXIT_FAILURE); } else { memset(p->Dhb,0,DEFAULT*sizeof(Peo)); p->count=0; p->capacity=DEFAULT; } } void cheak_cap(pCon p) //检查通讯录当前容量大小 { if(p->count==p->capacity) { Peo *ptr=(Peo *)realloc(p->Dhb,(p->count+INC_SZ)*sizeof(Peo)); if(ptr==NULL) { printf("out of memory\n"); exit(EXIT_FAILURE); } else { p->Dhb=ptr; p->capacity+=INC_SZ; } } } void add_peo(pCon p) //添加联系人信息 { cheak_cap(p); printf("请输入姓名:"); scanf("%s",p->Dhb[p->count].name); printf("请输入性别:"); scanf("%s",p->Dhb[p->count].sex); printf("请输入年龄:"); scanf("%d",&p->Dhb[p->count].age); printf("请输入电话:"); scanf("%s",p->Dhb[p->count].tele); printf("请输入住址:"); scanf("%s",p->Dhb[p->count].address); p->count++; printf("添加联系人成功\n"); } int find_peo(pCon p,char *name)//查找指定的联系人 { int i=0; if(p->count==0) { printf("通讯录为空\n"); } for(i=0;i<p->count;i++) { if(strcmp(p->Dhb[i].name,name)==0) return i; } return -1; } void del_peo(pCon p) //删除指定联系人信息 { char name[MAX_NAME]={0}; int i=0; int ret=0; printf("请输入要删除的联系人姓名:"); scanf("%s",name); ret=find_peo(p,name); if(ret!=-1) { for(i=ret;i<p->count-1;i++) { p->Dhb[i]=p->Dhb[i+1]; } p->count--; Sleep(2000); printf("删除成功!!!\n"); } else { printf("没有此联系人\n"); } } void serch_peo(pCon p) //查找指定联系人并输出其信息 { char name[MAX_NAME]={0}; int i=0; int ret=0; printf("请输入要查找的联系人姓名:"); scanf("%s",name); ret=find_peo(p,name); if(ret!=-1) { printf("%s ",p->Dhb[ret].name); printf("%s ",p->Dhb[ret].sex); printf("%d ",p->Dhb[ret].age); printf("%s ",p->Dhb[ret].tele); printf("%s",p->Dhb[ret].address); printf("\n"); } else { printf("此联系人不存在\n"); } } void mod_peo(pCon p) //修改指定联系人信息 { char name[MAX_NAME]={0}; int i=0; int ret=0; printf("请输入要修改的联系人姓名:"); scanf("%s",name); ret=find_peo(p,name); if(ret!=-1) { printf("请输入需要修改的姓名:"); scanf("%s",p->Dhb[ret].name); printf("请输入需要修改的性别:"); scanf("%s",p->Dhb[ret].sex); printf("请输入需要修改的年龄:"); scanf("%d",&p->Dhb[ret].age); printf("请输入需要修改的电话:"); scanf("%s",p->Dhb[ret].tele); printf("请输入需要修改的住址:"); scanf("%s",p->Dhb[ret].address); printf("修改此联系人成功\n"); } else { printf("此通讯录中没有此联系人\n"); } } void show_peo(pCon p) //显示所有联系人信息 { int i=0; printf("输出所有联系人信息为:\n"); printf("%5s\t%5s\t%5s\t%5s\t%10s\n","name","sex","age","tele","address"); for(i=0;i<p->count;i++) { printf("%5s ",p->Dhb[i].name); printf("%5s ",p->Dhb[i].sex); printf("%5d ",p->Dhb[i].age); printf("%5s ",p->Dhb[i].tele); printf("%10s",p->Dhb[i].address); printf("\n"); } } void empty_peo(pCon p) //清空所有联系人信息 { p->count=0; Sleep(2000); printf("清空完成\n"); } void sort_peo(pCon p) //用名字排序所有联系人信息 { int i=0; int flag=0; for(i=0;i<(p->count)-1;i++) { int j=0; flag=0; for(j=0;j<(p->count)-1-i;j++) { if(strcmp(p->Dhb[j].name,p->Dhb[j+1].name)>0) { Peo tmp=p->Dhb[j]; p->Dhb[j]=p->Dhb[j+1]; p->Dhb[j+1]=tmp; flag=1; } } if(flag==0) break; } Sleep(2000); printf("排序完成\n"); } void destory_Dhb(pCon p) //释放动态开辟的内存 { if(p->Dhb!=NULL) { free(p->Dhb); p->Dhb=NULL; } }
test.c
#include "contact.h" void menu() { printf("*********************************************\n"); printf("**************1.添加联系人信息***************\n"); printf("**************2.删除指定联系人***************\n"); printf("**************3.查找指定联系人***************\n"); printf("**************4.修改指定联系人***************\n"); printf("**************5.显示所有联系人***************\n"); printf("**************6.清空所有联系人***************\n"); printf("**************7.排序所有联系人***************\n"); printf("**************0.退出 ***************\n"); printf("*********************************************\n"); } void test() { Con con; int input=1; init_peo(&con); while(input) { menu(); printf("请选择>:"); scanf("%d",&input); switch(input) { case ADD: { add_peo(&con); break; } case DEL: { del_peo(&con); break; } case SERCH: { serch_peo(&con); break; } case MOD: { mod_peo(&con); break; } case SHOW: { show_peo(&con); break; } case EMPTY: { empty_peo(&con); break; } case SORT: { sort_peo(&con); break; } case EXIT: { destory_Dhb(&con); exit(1); break; } default: { printf("请输入正确选项\n"); break; } } } } int main() { test(); system("pause"); return 0; }