通讯录升级--可增容(动态增长空间)

news/2024/10/30 15:20:24/

通讯录成员的改变

之前我们定义了date[100]的数组用来存放100个人的信息,但是当需要存储的人数超过100时,内存不够,存储人数较少时,又有些浪费,并且数组空间在创建时就已经确立,无法随需求改变,因此我们希望让它可以动态变化。

这里我默认初始为3,每次不够了就增容2。(为了方便测试)

#define once_sz 2
#define init_sz 3

第一个参数为每次增容2,第二个参数为初始化为3.

typedef struct contact
{peopleinfo *date;int sz;int capacity;
}contact;

将date[n]改为一个peopleinfo类型的指针,便于接收我们调用内存分配函数后返回的void*起始地址

sz仍然表示现在已经有的人员信息数

新增capacity成员,用来表示现有的通讯录容量。

 

通讯录初始化

 void contact_init(contact* pc)
{assert(pc);pc->sz = 0;pc->capacity = init_sz;peopleinfo* ptr = (peopleinfo*)calloc(init_sz,sizeof(peopleinfo));if (NULL == ptr)//中间变量str判断是否成功开辟了一块空间{perror("contact_init:calloc");return;}pc->date = str;str=NULL:
}

sz初始化为0,capacity初始化为init_sz

然后利用calloc函数进行动态内存开辟,第一个参数为块数,第二个为每块空间的大小,因为每个元素都是人员信息peopleinfo,所以强制转换为peopleinfo。

然后创建一个中间变量ptr用来判断返回值是否为NULL,即是否成功开辟一块空间,判断完后,将ptr赋给date,用date指针来维护这一块空间,然后str可以置为空。

增加功能的升级

在增删查改、排序、显示功能中,仅增加和删除两个会改变当前的人员信息数,因此我们也要相应的增加/减少通讯录容量。

增加功能此前是判断sz是否达到最大元素sz,然后进行增加信息。

现在为了实现动态通讯录,我们增加增容功能,使其内存慢慢增加,按需增加,不再需要一个数组大小去限制它。

//增加人员信息
void contact_add(contact* pc)
{assert(pc);check_capacity(pc);//通讯录没满,添加信息printf("请输入姓名\n");scanf("%s", pc->date[pc->sz].name);printf("请输入年龄\n");scanf("%d", &pc->date[pc->sz].age);printf("请输入性别\n");scanf("%s", pc->date[pc->sz].sex);printf("请输入电话\n");scanf("%s", pc->date[pc->sz].tel);printf("请输入地址\n");scanf("%s", pc->date[pc->sz].dres);pc->sz++;
}

增容函数的实现

在增加人员信息前,先判断是否需要增容,如果需要,就进行增容。

当已有人员sz和capacity容量相同是需要增容。

增容过程利用realloc重新确定开辟空间的大小。

realloc第一个参数是重新开辟空间的起始地址,第二个是更新后的空间大小。

返回值用中间变量ptr接收,判断不为空指针后,用date指针来维护。

然后将ptr置空,相应的,容量capacity也要加上增量。


void check_capacity(contact* pc)
{if (pc->capacity == pc->sz){//相等时进行增容peopleinfo* ptr = (peopleinfo*)realloc(pc->date, (pc->capacity + once_sz) * sizeof(peopleinfo));if (NULL == ptr){perror("check_capacity:realloc");return;}pc->date = ptr;ptr = NULL;pc->capacity += once_sz;printf("增容成功\n");}
}

 当我们已有3个人员信息,再次添加后,显示增容成功。

减容函数的实现

当删除人员信息较多时,影响sz的量较大时,我们可以考虑减容以节省空间。

初始时,sz=0,capacity=3,差值为3,且相同时增量为2,因此我们可以在sz和capacity的差值大于3时进行减容。

#define d_value 3

这里我们定义一个减容的差值3,以后还可以改成其他数。

添加6个元素后,此时capacity为7,sz为6,现在开始删除元素

 

删除至3个,此时sz=3,capacity=7,差大于3,成功减容。 

退出时释放空间

前面我们多次使用malloc、calloc、realloc等内存开辟函数,但却没有释放,可能会导致内存泄漏问题,因此我们在退出通讯录时,一并进行释放操作。

//销毁通讯录
void contact_destroy(contact* pc)
{free(pc->date);pc->date = NULL;
}

将date指针指向的空间free,并将date置空即可。

动态内存开辟函数头文件是stdlib.h,返回地址要判断是否为空,还要进行free和置空操作。

目录

通讯录成员的改变

通讯录初始化

增加功能的升级

增容函数的实现

减容函数的实现

退出时释放空间



http://www.ppmy.cn/news/12758.html

相关文章

Linux IO: 系统调用 poll() 实现简析

1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 分析背景 本文基于 Linux 4.14 内核源码进行分析。 3. 系统调用 poll() 实现分析 3.1 调用的发起:用户空间 用户侧应用程序在查询…

React脚手架+组件化开发+组件生命周期+组件通信

react脚手架(create-react-app) 1.作用: 帮助我们生成一个通用的目录结构,并且已经将我们所需的工程环境配置好 2.依赖环境 脚手架都是使用node编写的,并且都是基于webpack的; 3.安装node 4.安装脚手架 n…

【web安全】——HTTP请求头注入

作者名:Demo不是emo主页面链接: 主页传送门创作初心: 舞台再大,你不上台,永远是观众,没人会关心你努不努力,摔的痛不痛,他们只会看你最后站在什么位置,然后羡慕或鄙夷座右…

【墙角数枝梅,凌寒独自开】代码改变未来

墙角数枝梅,凌寒独自开 “墙角数枝梅,凌寒独自开。” 出自王安石的《梅花》 诗句是集语言中的精华,浓缩为七言、五言和四言等,寥寥几句道尽人生酸甜苦辣,儿女情长。 而我更愿把现代的程序员称作诗人,语言是…

《Linux Shell脚本攻略》学习笔记-第十二章

12.1 简介 我们可以通过关闭无用的服务、调整内核参数或是添加新的硬件来改善系统性能。 12.2 识别服务 Linux系统可以同时运行数百个任务,其中可能也会有那么一两个你不需要的守护进程。 有三种可以用于启动守护进程和服务的工具,Linux发行版支持其中任…

亚马逊云科技 Build On - 毫厘控制传统行业快速搭建部署智能业务这件事“钱花在刀刃上”——迎云计算更高一层精专形态的下一个时代Serverless

/*本文章总计6052词,可能需要16分钟进行阅读,创作时间近1周,尽量将Serverless干货打包满满,并尝试向您解释清楚。 无论是路过还是看得乐呵的看官姥爷只求能给个👍点赞和⭐收藏,谢谢您嘞❤ P.S.CSDN侧边可以…

Rancher 2022 关键主题与新年展望

作者简介 张智博,SUSE Rancher 大中华区研发总监,一直活跃在研发一线,经历了 OpenStack 到 Kubernetes 的技术变革,在底层操作系统 Linux、虚拟化 KVM 和 Docker 容器技术领域都有丰富的研发和实践经验。 以 Rancher 为核心的 SUS…

c++11 标准模板(STL)(std::forward_list)(十)

定义于头文件 <forward_list> template< class T, class Allocator std::allocator<T> > class forward_list;(1)(C11 起)namespace pmr { template <class T> using forward_list std::forward_list<T, std::pmr::polymorphic_…