> 文档中心 > 【C语言】通讯录《动态内存版本》

【C语言】通讯录《动态内存版本》


🚩write in front🚩   

🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家博主 & 星级博主~掘金⇿InfoQ~51CTOP创作者~周榜109﹣总榜883⇿全网访问量35w+🏅
🆔本文由 謓泽 原创 CSDN首发🙉如需转载还请通知⚠
📝个人主页-謓泽的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​
📣系列专栏-YY_謓泽的博客-CSDN博客🎓
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩

​​

目录

🚩write in front🚩   

前言

动态内存版本 

代码改动 

模块化代码实现

address_book.c

address_book.h

test.c

最后

前言

这篇博客带大家实现通讯录的一个动态内存增长的一个版本,在上一片博客当中我们介绍了通讯录静态版本的一个实现,如果对静态版本感兴趣的话可以看看ヾ(^▽^*)))

✨链接→【C语言】通讯录《静态内存版本》_謓泽的博客-CSDN博客✨

动态内存版本 

①:通讯录初始化后,能够存放三个人的信息。当然实际上这里多少都是可以的,只不过这个比较好测试。

②:当我们空间的存放存放满的时候,再次增加两个人的信息。

当然如果你不熟悉什么是动态内存的话,可以看看博主写的这篇博客ヾ(^▽^*)))

✨链接→【C语言】动态内存开辟的使用『malloc』✨

代码改动 

根据上篇的静态通讯录进行了一点改动,改动如下所示👇

通讯录 ✨ 静态版本 →(改编成) 通讯录 ✨ 动态版本

还改变了点宏定义把原先1000人存放进来的信息删除了,增加了"容器"以及增量。

InitContact()增加人的信息,放在通讯录当中去从静态版本 ✨ →(改编成) ✨ 动态版本。

Destory_Contact()增加了一个销毁通讯录。

说明⇢在这里给大家看看程序增容后的运行界面。在这里我们的"容器值"最大为三每次增量加2的。 

​​

这里是当我们输入第三次添加之后就会出现增加联系人成功(@^0^),表明我们已经动态内存开辟增容成功。

​​

此时,再输入就会显示增加联系人成功,因为我们每次增量加2的。内存空间已满又要向堆区申请内存空间。

模块化代码实现

​​

address_book.c

示例代码如下↓ 

#define _CRT_SECURE_NO_WARNINGS 1#include"address_book.h"//动态版本void InitContact(Contact* pc){pc->date = (information*)malloc(Defsz * sizeof(information));//如果返回的为空指针的情况if (pc->date == NULL){perror("InitContact:");return;}pc->sz = 0;//sz初始化pc->capacity = Defsz;//当前最大"容量"}//动态版本增加void Add_Contact(Contact* pc){//当记录当前通讯录有效信息的个数 等于 表示当前通讯录的最大"容量"大小。if (pc->sz == pc->capacity){//给堆区增加"容量",因为空间不够。information* pa = (information*)realloc(pc->date, (pc->capacity + Inc)*(sizeof(information)));if (pa != NULL){pc->date = pa;//把这块空间移交到date进行维护pc->capacity = pc->capacity + Inc;//由于这里我们进行了增容也需要把容量改变成+Inc的值color(12);printf("增加联系人已成功(@^0^)\n");}//增容失败else{perror("Add_Contact:");printf("增加联系人失败!(ToT)/~~~\n");return;}}//增加一个人的信息printf("\n");printf("请输入增加人的名字->:");scanf("%s", pc->date[pc->sz].name);//注意→数组名是首元素地址,所以不用进行取地址.printf("请输入增加人的年龄->:");scanf("%s", pc->date[pc->sz].age);printf("请输入增加人的性别->:");scanf("%s", pc->date[pc->sz].genger);printf("请输入增加人的电话->:");scanf("%s", pc->date[pc->sz].telephone);printf("请输入增加人的地址->:");scanf("%s", pc->date[pc->sz].address);//成功~pc->sz++;printf("★恭喜你~添加信息成功★\n");printf("\n");}void Print_Contact(const Contact* pc){int i = 0;//打印标题栏的信息printf("|-------------------------------------------------------|\n");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i sz; i++){printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[i].name,pc->date[i].age,pc->date[i].genger,pc->date[i].telephone,pc->date[i].address);}}static int FindByname(Contact* pc, char name[]){int i = 0;//用for循环进行遍历for (i = 0; i sz; i++){//strcmp()比较字符串if (strcmp(pc->date[i].name, name) == 0){return i;//返回下标}}return -1;}void DeLete_Contact(Contact* pc){char name[Max_name] = { 0 };//通讯录为空的时候if (pc->sz == 0){printf("通讯录当中没有任何信息\n");return;}printf("请输入你要删除的名字->:");scanf("%s", name);//查找要删除的人:有/没有int ret = FindByname(pc, name);if (ret == -1){printf("没有查找到当前人的信息\n");return;}//删除int i = 0;for (i = ret; i sz - 1; i++){pc->date[i] = pc->date[i + 1];}pc->sz--;//因为我们删除成功下标要减1printf("★恭喜你~删除信息成功★\n");printf("\n");}void Find_Contact(Contact* pc){char name[Max_name] = { 0 };printf("请输入你要查找的名字->:");scanf("%s", name);int ret = FindByname(pc, name);if (ret == -1){printf("没有查找到当前人的名字\n");return;}else{printf("|-------------------------------------------------------|\n");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[ret].name,pc->date[ret].age,pc->date[ret].genger,pc->date[ret].telephone,pc->date[ret].address);printf("查找%sの信息成功~\n", pc->date[ret].name);}}void Revise_Contact(Contact* pc){char name[Max_name] = { 0 };printf("请输入你要修改通讯录人的名字->:");scanf("%s", name);int ret = FindByname(pc, name);if (ret == -1){printf("当前修改人的信息不存在\n");return;}else{printf("请输入修改人的名字->:");scanf("%s", pc->date[ret].name);//注意→数组名是首元素地址,所以不用进行取地址.printf("请输入修改人的年龄->:");scanf("%s", pc->date[ret].age);printf("请输入修改人的性别->:");scanf("%s", pc->date[ret].genger);printf("请输入修改人的电话->:");scanf("%s", pc->date[ret].telephone);printf("请输入修改人的地址->:");scanf("%s", pc->date[ret].address);printf("恭喜你,修改成功~\n");}}int sort_name_max(const void* e1, const void* e2){return (strcmp(((struct Contact*)e1)->date->name, ((struct Contact*)e2)->date->name));}void Check_Contact(Contact* pc){//qosrt()函数首字母进行排序qsort(pc->date, pc->sz, sizeof(pc->date[0]), sort_name_max);printf("|-------------------------------------------------------|\n");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i sz; i++){printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[i].name,pc->date[i].age,pc->date[i].genger,pc->date[i].telephone,pc->date[i].address);}}void Destory_Contact(Contact* pc){//销毁通讯录实际上就是把date给释放掉,free()函数进行回收即可。free(pc -> date);pc->date = NULL;pc->sz = 0;pc->capacity = 0;//记得清0☆⌒(*^-゜)v THX!!}

address_book.h

示例代码如下↓  

#define _CRT_SECURE_NO_WARNINGS 1#include #include#include#include#define Max_name 5#define Max_age 100#define Max_genger 3#define Max_address 20#define Max_telephone 20#define Defsz 3 //一开始的值#define Inc 2  //每次的增量//类型的定义typedef struct information{//名字、年龄、性别、电话、地址。char name[Max_name];char age[Max_age];char genger[Max_genger];char telephone[Max_telephone];char address[Max_address];}information;//初始化通讯录void InitContact(Contact* pc);//增加通讯录信息void Add_Contact(Contact* pc);//打印通讯录的信息void Print_Contact(const Contact* pc);//删除通讯人的信息void DeLete_Contact(Contact* pc);//查找指定通讯录人的信息void Find_Contact(Contact* pc);//修改指定通讯录人的信息void Revise_Contact(Contact* pc);//排查通讯录当中人员的信息void Check_Contact(Contact* pc);//销毁通讯录void Destory_Contact(Contact* pc);

test.c

示例代码如下↓  

#include"address_book.h"#include//颜色函数void color(short x){if (x >= 0 && x <= 15)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);elseSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);}//创建菜单函数void menu(){color(0);//黑色system("cls");//清屏color(12);//白色printf("¤--------------------------------------------¤\n");printf("|■■■■■■■■→通讯录v1.0←■■■■■■■■|\n");printf("|———————————————————————|\n");printf("|★★★★★→1.increase ■ 2.deLete←★★★★★|\n");printf("|★★★★★→3.find     ■ 4.Revise←★★★★★|\n");printf("|★★★★★→5.Check    ■ 6.Print ←★★★★★|\n");printf("|★★★★★→0.Exit     ■  ←★★★★★|\n");printf("|———————————————————————|\n");printf("|■■■■■■■■→通讯录v1.0←■■■■■■■■|\n");printf("¤--------------------------------------------¤\n");}enum Number{Exit,Increase,DeLete,Find,Revise,Check,Print,};int main(void){menu();int input = 0;//当然初始化全0:Contact con = {0};也是可以的,当然我们这里的初始化不是这样的原因是可以应对比较复杂的问题。Contact con;//初始化通讯录//给date申请一块连续的内存空间存放在堆区上。InitContact(&con);do{color(5);printf("¤----------------¤\n");printf("|请输入界面上的数字|:");scanf("%d", &input);printf("¤----------------¤\n");color(1);switch (input){case Exit://把通讯录里面的内存空间date给释放掉。Destory_Contact(&con);//销毁通讯录。printf("══════════════@\n");printf("退出通讯录v1.0@\n");printf("══════════════@\n");break;case Increase://增加人的信息,放在通讯录当中去。Add_Contact(&con);break;case DeLete://删除通讯人的信息DeLete_Contact(&con);break;case Find://查找指定通讯录人的信息Find_Contact(&con);break;case Revise://修改指定通讯录人的信息Revise_Contact(&con);break;case Check://排查通讯录当中人员的信息Check_Contact(&con);break;case Print://打印通讯录当中人员的信息。Print_Contact(&con);break;default:printf("你输入的数字找不到,请重新输入~\n");}} while (input);return 0;}

最后

以上就是实现动态内存的实现方法了(^∀^●)ノシ。