建设网站公司兴田德润在哪里,wordpress中国官网,交通建设集团网站,fomo3d网站开发大家好#xff0c;我是苏貝#xff0c;本篇博客带大家优化上一篇的通讯录#xff0c;如果你觉得我写的还不错的话#xff0c;可以给我一个赞#x1f44d;吗#xff0c;感谢❤️ 目录 一. 前言二. 动态通讯录2.1 通讯录结构体2.2 初始化通讯录2.3 增加联系人2.4 销毁通讯… 大家好我是苏貝本篇博客带大家优化上一篇的通讯录如果你觉得我写的还不错的话可以给我一个赞吗感谢❤️ 目录 一. 前言二. 动态通讯录2.1 通讯录结构体2.2 初始化通讯录2.3 增加联系人2.4 销毁通讯录 三. 模块化代码实现3.1 test.c3.2 contact.h3.3 contact.c3.4 结果演示 一. 前言
在上一篇博文 实现通讯录管理系统 的最后我们了解了那段代码的问题通讯录的大小是固定的100个元素如果想要存放1000个人的信息那么空间就不够了如果信息太少只想存10个人的信息那么空间就大了。即使可以在源代码中修改#define定义的值解决也不免有些麻烦。怎么解决?用动态内存管理!
本篇博文要实现通讯录管理系统假设初始时只能存储3个人的信息若超过三人则通讯录容量2再存储联系人信息 二. 动态通讯录
我们从test.c文件中往下看明白要修改的代码
2.1 通讯录结构体
在test.c文件中我们先定义了通讯录变量。那么通讯录类型是否需要修改呢人的信息的结构体类型自然是不用修改的
typedef struct PeoInfo
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;但是通讯录类型似乎需要修改。因为静态版本中规定了通讯录最大存储100个人的信息而我们的优化是用malloc函数和realloc函数实现动态管理通讯录所以从静态版本的data数组到动态版本的data指针指向之后用malloc函数开辟的空间。除了要知道当前通讯录中存放的人的信息的个数我们也要知道通讯录的容量。当存放的人的信息的个数通讯录的容量时我们就应该要增加容量了
//静态版本
//typedef struct Contact
//{
// PeoInfo data[MAX];
// int sz;
//}Contact;//动态版本
typedef struct Contact
{PeoInfo *data;int sz;//当前通讯录中存放的人的信息的个数int capacity;//通讯录的容量
}Contact;2.2 初始化通讯录
静态初始化时是将sz的值赋值为0再将data数组中的内容全部初始化为0。动态初始化时sz也要被赋值为0通讯录容量capacity要被赋值为33是#define定义的标识符常量。将malloc函数或者calloc函数开辟的空间的起始位置的地址传给指针变量data因为需要将开辟的空间全初始化为0所以使用calloc函数。最后要判断空间是否开辟成功如果不成功就会返回NULL所以要对指针变量data判断
//静态初始化通讯录
//void InitContact(Contact* pc)
//{
// assert(pc);
// pc-sz 0;
// memset(pc-data, 0, sizeof(pc-data));
//}//动态初始化通讯录
void InitContact(Contact* pc)
{assert(pc);pc-sz 0;pc-capacity DEFAULT_CAP;//3pc-data (PeoInfo*)calloc(pc-capacity, sizeof(PeoInfo));if (pc-data NULL){perror(InitContact_calloc);return;}
}2.3 增加联系人
静态通讯录中增加联系人时要先判断通讯录是否满了那我们动态通讯录中也需要判断通讯录是否满了如果满了那就要增加通讯录的容量。用realloc函数修改开辟的内存空间的大小每次增容时容量增加22是#define定义的标识符常量。判断增容是否成功如果指针变量tmp是NULL开辟失败。如果不是那将变量tmp赋值给指针变量data
//静态增加联系人
//void AddContact(Contact* pc)
//{
// assert(pc);
// if (pc-sz MAX)
// {
// printf(通讯录已满增加失败\n);
// return;
// }
// printf(请输入名字);
// scanf(%s,pc-data[pc-sz].name );
// printf(请输入年龄);
// scanf(%d, (pc-data[pc-sz].age));
// printf(请输入性别);
// scanf(%s, pc-data[pc-sz].gender);
// printf(请输入电话);
// scanf(%s, pc-data[pc-sz].tele);
// printf(请输入地址);
// scanf(%s, pc-data[pc-sz].addr);
//
// pc-sz;
// printf(增加成功\n);
//}//动态增加联系人
void AddContact(Contact* pc)
{assert(pc);//增容if (pc-sz pc-capacity){PeoInfo* tmp realloc(pc-data, (pc-capacity DEFAAULT_INI) * sizeof(PeoInfo));if (tmp NULL){perror(AddContact_realloc);return;}pc-data tmp;pc-capacity DEFAAULT_INI;printf(增容成功\n);}printf(请输入名字);scanf(%s, pc-data[pc-sz].name);printf(请输入年龄);scanf(%d, (pc-data[pc-sz].age));printf(请输入性别);scanf(%s, pc-data[pc-sz].gender);printf(请输入电话);scanf(%s, pc-data[pc-sz].tele);printf(请输入地址);scanf(%s, pc-data[pc-sz].addr);pc-sz;printf(增加成功\n);
}2.4 销毁通讯录
因为使用了动态内存开辟空间所以最好在退出程序前释放掉所开辟的空间
void DestroyContact(Contact* pc)
{free(pc-data);pc-data NULL;
}三. 模块化代码实现
3.1 test.c
#includecontact.hvoid menu()
{printf(-----------------------------------\n);printf(***********************************\n);printf(****** 1.Add 2.Del ******\n);printf(****** 3.Select 4.Modify ******\n);printf(****** 5.Show 6.sort ******\n);printf(****** 0.exit ******\n);printf(***********************************\n);printf(-----------------------------------\n);
}enum Option
{EXIT,ADD,DEL,SELECT,MODIFY,SHOW,SORT
};int main()
{Contact con;//初始化通讯录InitContact(con);int input 0;do{ menu();printf(请选择);scanf(%d, input);switch (input){case ADD:AddContact(con);break;case DEL:DelContact(con);break;case SELECT:SelectContact(con);break;case MODIFY:ModifyContact(con);break;case SHOW:ShowContact(con);break;case SORT:SortContact(con);break;case EXIT:printf(退出程序\n);DestroyContact(con);break;default:printf(选择错误请重新选择\n);break;}} while (input);return 0;
}3.2 contact.h
#pragma once#includestdio.h
#includeassert.h
#includestring.h
#includestdlib.h#define NAME_MAX 20
#define GENDER_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30//#define MAX 1000#define DEFAULT_CAP 3
#define DEFAAULT_INI 2typedef struct PeoInfo
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;//静态版本
//typedef struct Contact
//{
// PeoInfo data[MAX];
// int sz;
//}Contact;//动态版本
typedef struct Contact
{PeoInfo *data;int sz;//当前通讯录中存放的人的信息的个数int capacity;//通讯录的容量
}Contact;//初始化通讯录
void InitContact(Contact* pc);//增加联系人
void AddContact(Contact* pc);//删除联系人
void DelContact(Contact* pc);//打印通讯录
void ShowContact(Contact* pc);//查找联系人
void SelectContact(Contact* pc);//修改联系人信息
void ModifyContact(Contact* pc);//以名字排序所有联系人
void SortContact(Contact* pc);//销毁通讯录
void DestroyContact(Contact* pc);3.3 contact.c
#includecontact.h//静态初始化通讯录
//void InitContact(Contact* pc)
//{
// assert(pc);
// pc-sz 0;
// memset(pc-data, 0, sizeof(pc-data));
//}//动态初始化通讯录
void InitContact(Contact* pc)
{assert(pc);pc-sz 0;pc-capacity DEFAULT_CAP;pc-data (PeoInfo*)calloc(pc-capacity, sizeof(PeoInfo));if (pc-data NULL){perror(InitContact_calloc);return;}
}//静态增加联系人
//void AddContact(Contact* pc)
//{
// assert(pc);
// if (pc-sz MAX)
// {
// printf(通讯录已满增加失败\n);
// return;
// }
// printf(请输入名字);
// scanf(%s,pc-data[pc-sz].name );
// printf(请输入年龄);
// scanf(%d, (pc-data[pc-sz].age));
// printf(请输入性别);
// scanf(%s, pc-data[pc-sz].gender);
// printf(请输入电话);
// scanf(%s, pc-data[pc-sz].tele);
// printf(请输入地址);
// scanf(%s, pc-data[pc-sz].addr);
//
// pc-sz;
// printf(增加成功\n);
//}//动态增加联系人
void AddContact(Contact* pc)
{assert(pc);//增容if (pc-sz pc-capacity){PeoInfo* tmp realloc(pc-data, (pc-capacity DEFAAULT_INI) * sizeof(PeoInfo));if (tmp NULL){perror(AddContact_realloc);return;}pc-data tmp;pc-capacity DEFAAULT_INI;printf(增容成功\n);}printf(请输入名字);scanf(%s, pc-data[pc-sz].name);printf(请输入年龄);scanf(%d, (pc-data[pc-sz].age));printf(请输入性别);scanf(%s, pc-data[pc-sz].gender);printf(请输入电话);scanf(%s, pc-data[pc-sz].tele);printf(请输入地址);scanf(%s, pc-data[pc-sz].addr);pc-sz;printf(增加成功\n);
}int FindOfName(char* name, Contact* pc)
{assert(name pc);int i 0;for (i 0; i pc-sz; i){if (0 strcmp(name, (pc-data[i].name)))return i;}return -1;
}//删除联系人
void DelContact(Contact* pc)
{assert(pc);char name[NAME_MAX] { 0 };if (pc-sz 0){printf(通讯录为空删除失败\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要删除的人\n);return;}int i 0;for (i ret; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n);
}//打印通讯录
void ShowContact(Contact* pc)
{assert(pc);if (pc-sz 0){printf(通讯录为空打印无意义\n);return;}int i 0;printf(%-20s%-5s%-5s%-30s%-30s\n, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){printf(%-20s%-5d%-5s%-30s%-30s\n, pc-data[i].name, pc-data[i].age,pc-data[i].gender, pc-data[i].tele, pc-data[i].addr);}
}//查找联系人
void SelectContact(Contact* pc)
{char name[NAME_MAX] { 0 };printf(请输入要查找的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要查找的人\n);return;}printf(%-20s%-5s%-5s%-30s%-30s\n, 姓名, 年龄, 性别, 电话, 地址);printf(%-20s%-5d%-5s%-30s%-30s\n, pc-data[ret].name, pc-data[ret].age,pc-data[ret].gender, pc-data[ret].tele, pc-data[ret].addr);
}//修改联系人信息
void ModifyContact(Contact* pc)
{assert(pc);char name[NAME_MAX] { 0 };printf(请输入要修改的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要修改的人\n);return;}printf(请输入名字);scanf(%s, pc-data[ret].name);printf(请输入年龄);scanf(%d, (pc-data[ret].age));printf(请输入性别);scanf(%s, pc-data[ret].gender);printf(请输入电话);scanf(%s, pc-data[ret].tele);printf(请输入地址);scanf(%s, pc-data[ret].addr);
}int cmp(const void* a, const void* b)
{return strcmp((char*)a, (char*)b);
}//以名字排序所有联系人
void SortContact(Contact* pc)
{assert(pc);qsort(pc-data, pc-sz, sizeof(pc-data[0]), cmp);printf(排序成功\n);
}//销毁通讯录
void DestroyContact(Contact* pc)
{free(pc-data);pc-data NULL;
}3.4 结果演示
因为在6个功能中只修改了增加联系人信息这一个功能其余5个功能并未修改因此结果演示中只演示通讯录容量不够时增容的情况 好了那么本篇博客就到此结束了如果你觉得本篇博客对你有些帮助可以给个大大的赞吗感谢看到这里我们下篇博客见❤️