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

通讯录成员的改变

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

目录

通讯录成员的改变

通讯录初始化

增加功能的升级

增容函数的实现

减容函数的实现

退出时释放空间


  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值