[C Language] Dynamic storage version of address book

Table of contents

I. Introduction

2. Why dynamic storage?

1. The role of dynamic storage:

2The difference between dynamic and static storage:

3. Implementation of dynamic storage

1. Address book capacity

2.Initialize address book

3. Add/reduce address book members

Add address book members

Determine and implement the expansion function

Reduce address book members

Judgment and implementation of capacity reduction function

4.Reset address book

5. Exit the address book

 4. Conclusion


I. Introduction

This article is in the previous address book source code (link: https://blog.csdn.net/qq_74641564/article/details/128741939) On the basis of optimization, to achieve dynamic storage of address book members.

2. Why dynamic storage?

1. The role of dynamic storage:

Dynamic storage can achieve more reasonable allocation and use of memory resources

2The difference between dynamic and static storage:

The data in the static version does not have the convenience and flexibility of memory allocation in the dynamic version.

Taking the static address book as an example, it is obvious. If a static address book needs to store the information of 100 or even 1,000 people, then the data of these people created in advance will occupy a large amount of memory space, or even overflow. However, If there are several people and only a few people's data is stored, wouldn't it be possible to avoid wasting memory?

3. Implementation of dynamic storage

1. Address book capacity

Delete the original member structure array and replace it with the member structure pointer. At the same time, you need to create a new variable to represent the amount of each expansion and reduction.

typedef struct Contact
{
	ContactMember* data;
	int sz;
	int capacity;
}Contact;

2.Initialize address book

Use the calloc function to apply for a certain amount of space of the size of the member structure, and create a ptr here to prevent a NULL pointer from being returned.

//初始化成员信息
//DEFAULT_SIZE定义为常量
void InitContact(Contact* con)
{
	assert(con);
	con->sz = 0;

    //申请空间
	ContactMember* ptr = (ContactMember*)calloc(DEFAULT_SIZE , sizeof(ContactMember));
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}
	con->data = ptr;

	con->capacity = DEFAULT_SIZE;
}

3. Add/reduce address book members

Add address book members

If the previously applied space is used up, the originally applied space needs to be expanded to store more member data. Therefore, before adding address book members, determine whether the current capacity needs to be expanded.

void AddContact(Contact* con)
{
	assert(con);

    //检查扩容
	check_capacity(con);

	printf("请输入姓名:");
	scanf("%s", con->data[con->sz].Name);
	printf("请输入性别:");
	scanf("%s", con->data[con->sz].Sex);
	printf("请输入年龄:");
	scanf("%d", &con->data[con->sz].Age);
	printf("请输入住址:");
	scanf("%s", con->data[con->sz].Address);
	printf("请输入号码:");
	scanf("%s", con->data[con->sz].Number);
	printf("输入完毕!\n");

	con->sz++;
}

Determine and implement the expansion function

Use the realloc function to expand the original capacity. Similarly, the returned pointer must also be judged. If you directly return a NULL pointer, there will be a big problem...

//检查增容
void check_capacity(Contact* con)
{
	if (con->sz == con->capacity)
	{
		ContactMember* ptr = (ContactMember*)realloc(con->data, (con->capacity + Capacity) * sizeof(ContactMember));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
			return;
		}
		con->data = ptr;
		con->capacity += Capacity;
		printf("扩容成功!\n");
	}
}

Reduce address book members

Similar to adding, but you need to nest the judgment function after reducing the member.

void DelContact(Contact* con)
{
	assert(con);

	if (con->sz == 0)
	{
		printf("没有可以删除的目标!\n");
		return;
	}

	printf("请输入目标删除人:");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindName(con, name);
	if (ret == -1)
	{
		printf("目标人物不存在!\n");
		return;
	}
	memmove(con->data + ret, con->data + ret + 1, sizeof(con->data[0]) * (con->sz - ret - 1));
	printf("删除成功!\n");
	con->sz--;

    //判断减容
	check_del_capacity(con);
}

Judgment and implementation of capacity reduction function

Like the increment function, only the plus and minus signs change.

//检查减容
void check_del_capacity(Contact* con)
{
	if (con->sz <= con->capacity - Capacity && con->capacity >= DEFAULT_SIZE)
	{
		ContactMember* ptr = (ContactMember*)realloc(con->data, (con->capacity - Capacity) * sizeof(ContactMember));
		if (ptr == NULL)
		{
			perror("check_del_capacity::realloc");
			return;
		}
		con->data = ptr;
		con->capacity -= Capacity;
		printf("减容成功!\n");
	}
}

4.Reset address book

As the saying goes, things are borrowed and returned. Since you have applied for a certain amount of space before, you must return it when you no longer need it. When resetting, you must free (release) all the previously applied memory, and then reapply for the original size of space. Of course, the realloc function can also be implemented, it’s your choice.

void EmptyContact(Contact* con)
{
	assert(con);

	//释放前者内存
	free(con->data);
	con->data = NULL;

    //重置
	con->sz = 0;
	ContactMember* ptr = (ContactMember*)calloc(DEFAULT_SIZE, sizeof(ContactMember));
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return;
	}
	con->data = ptr;
	con->capacity = DEFAULT_SIZE;

	printf("重置成功!\n");
}

5. Exit the address book

You cannot use the function to reset the address book when exiting the address book, because this will apply for another space, and we only need to return the memory.

//退出通讯录
void DestoryContact(Contact* con)
{
	con->capacity = 0;
	con->sz = 0;
	free(con->data);
	con->data = NULL;
	con = NULL;
}

 4. Conclusion

Finally, don’t forget to replace the modified data. Let’s work hard together to get the offer you like!

Guess you like

Origin blog.csdn.net/qq_74641564/article/details/128844827