当前位置: 首页 > news >正文

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

通讯录成员的改变

之前我们定义了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和置空操作。

目录

通讯录成员的改变

通讯录初始化

增加功能的升级

增容函数的实现

减容函数的实现

退出时释放空间


相关文章:

  • 猪八戒网做网站怎么样/百度快照优化推广
  • wordpress菜单的意思/新闻头条今日要闻
  • 跨境电商网站建设/新疆疫情最新情况
  • 网站开发服务器框架/上海优化关键词的公司
  • wordpress 滚动定位 插件/东莞做网站的联系电话
  • 南充响应式网站建设/怎么创建网页
  • 【PCB专题】为什么需要确认工作稿
  • 【UE4 第一人称射击游戏】51-制作手榴弹
  • 本地挂载网盘_Alist_RaiDrive_windows
  • 如何在Windows上同时搭建多个版本的golang环境——g
  • jQuery(一):选择器、样式操作、动画效果
  • HTML零基础教程,九大知识点带你玩转前端(上)
  • centos上用nginx搭建简单的点播服务器
  • 通达信接口QQ是什么端口?
  • BIP流程关键点介绍
  • OpenCV(12)-OpenCV的机器学习
  • 《Stealth秘密行动》游戏开发记录
  • 蓝桥杯:整数分解