通讯录改进———动态版本

在上一篇博客中讲完了动态内存分配,这时候我们就可以改进之前写的通讯录了,可以将其升级为动态内存的版本,既不用担心联系人满了,也不用担心内存浪费太大。

要将其改为动态版本主要是两件事,首先初始化的时候我们要动态开辟data的空间,光动态开辟还不够,我们还要增加一个变量来记录当前联系人列表的大小,空间使用完之后要记得释放。其次,我们要控制动态内存增长,就是当联系人的数量与联系人列表的大小相等时,我们要对data扩容。

知道了思路,实现起来就很简单了。首先我们将联系人列表初始化一定的空间,假设我们设定初始最大联系人数量为3,我们可以在头文件中用#define来定义,方便后续修改.与此同时,我们也可以用#define来定义每次扩容的空间。同时对结构体增加一个变量size记录当前最大可容纳联系人数量。

#define INIT_SIZE 3
#define ADD_SIZE 2

typedef struct Contact
{
	People* data;
	size_t count;
	size_t size;
}Contact;

然后原来初始化通讯录的代码进行修改。

//动态版本初始化通讯录
void Init_Contact(Contact* pc)
{
	assert(pc);
	pc->data = (People*)malloc(sizeof(People) * INIT_SIZE);
	pc->size = INIT_SIZE;
	if (pc->data == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		*((pc->data[i]).name) = 0;
		(pc->data[i]).age = 0;
		*((pc->data[i]).sex) = 0;
		*((pc->data[i]).tele) = 0;
		*((pc->data[i]).address) = 0;
	}
	pc->count = 0;
}

当我们使用动态内存来实现通讯录时,为了方便释放内存,我们再写一个函数用来释放,在退出通讯录之前使用这个函数进行内存释放。

void Destroy_Contact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
	pc->size = 0;
	pc->count = 0;
}

接下来就要考虑增容的问题了,增容只会在Add中出现,我们将增容操作与判断size和count的关系写在一个函数Check里,每次进入Add函数之后,都要先使用一次Check函数来判断是否需要增容。

void Check(Contact* pc)
{
	assert(pc);
	if (pc->count == pc->size)//增容
	{
		People* ptr = (People*)realloc(pc->data,sizeof(People) * (pc->size + ADD_SIZE));
		if (ptr == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		pc->data = ptr;
	}
}

再对之前的一些小细节进行一些小修改,就能实现动态版本了。

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值