🚩write in front🚩
🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家博主 & 星级博主~掘金⇿InfoQ~51CTOP创作者~周榜109﹣总榜883⇿全网访问量35w+🏅
🆔本文由 謓泽 原创 CSDN首发🙉如需转载还请通知⚠
📝个人主页-謓泽的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏-YY_謓泽的博客-CSDN博客🎓
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩
目录
前言
这篇博客带大家实现通讯录的一个动态内存增长的一个版本,在上一片博客当中我们介绍了通讯录静态版本的一个实现,如果对静态版本感兴趣的话可以看看ヾ(^▽^*)))
✨链接→【C语言】通讯录《静态内存版本》_謓泽的博客-CSDN博客✨
动态内存版本
①:通讯录初始化后,能够存放三个人的信息。当然实际上这里多少都是可以的,只不过这个比较好测试。
②:当我们空间的存放存放满的时候,再次增加两个人的信息。
当然如果你不熟悉什么是动态内存的话,可以看看博主写的这篇博客ヾ(^▽^*)))
代码改动
根据上篇的静态通讯录进行了一点改动,改动如下所示👇
通讯录 ✨ 静态版本 →(改编成) 通讯录 ✨ 动态版本
还改变了点宏定义把原先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 < pc->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 < pc->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 < pc->sz - 1; i++) { pc->date[i] = pc->date[i + 1]; } pc->sz--;//因为我们删除成功下标要减1 printf("★恭喜你~删除信息成功★\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 < pc->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<stdio.h> #include<stdlib.h> #include<Windows.h> #include<string.h> #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<Windows.h> //颜色函数 void color(short x) { if (x >= 0 && x <= 15) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); else SetConsoleTextAttribute(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; }
最后
以上就是实现动态内存的实现方法了(^∀^●)ノシ。
【C语言】通讯录《动态内存版本》
于 2022-10-08 21:19:05 首次发布