这篇文章是在上期实现的通讯录基础上,增加了自动增容的功能,也解决了一开始通讯录自动开辟一个空间,可能会浪费空间,或者是信息过多无法增容的痛点,由于我们使用的是malloc这类函数来开辟空间,我们也需要来释放空间,所以我们定义了一个销毁通讯录的函数.
上期文章 :1.0版本
1.增容策略
这里我们也不用2倍或者是1.5倍增容,我们干脆就一开始给可以容纳三条信息的空间,后面每次增容两条信息的空间,主要是便于我们的测试,这里我们定义两个宏,便于我们以后来调整开始和增容的人数.
#define DEFAULT_SIZE 3 #define DEFAULT_INC 2
2.修改代码
2.1初始化
我们这里只需要修改三个地方的代码,首先是函数初始化的地方需要修改,我们需要将原来初始化为100的通讯录改成一开始初始化三个,然后每次扩容添加两个.
//静态版本 //void InitContact(Contact* pc) //{ // assert(pc); // pc->sz = 0; // memset(pc->data, 0, sizeof(pc->data)); //} //动态版本 void InitContact(Contact* pc) { assert(pc); pc->sz = 0; pc->capacity = DEFAULT_SIZE; pc->data = calloc(pc->capacity ,sizeof(PeoInfo)); if (pc->data == NULL) { perror("error"); return; } }
2.2 增容
接下来就是对添加函数进行修改了,这里我们将添加函数中的扩容功能封装成另一个函数,减少代码的耦合性,使得看起来更清爽.
//静态版本 //void AddContact(Contact* pc) //{ // assert(pc); // if (pc->sz == MAX) // { // printf("通讯录已满,无法增加"); // return; // } // printf("请输入名字:>\n"); // scanf("%s", pc->data[pc->sz].name); // printf("请输入年龄:>\n"); // scanf("%d", &(pc->data[pc->sz].age)); // printf("请输入性别:>\n"); // scanf("%s", (pc->data[pc->sz].sex)); // printf("请输入电话:>\n"); // scanf("%s", (pc->data[pc->sz].tele)); // printf("请输入地址:>\n"); // scanf("%s", (pc->data[pc->sz].addr)); // pc->sz++; // printf("增加成功\n"); //} //动态版本 void CheckCapacity(Contact* pc) { if (pc->sz == pc->capacity) { PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + DEFAULT_INC) * sizeof(PeoInfo)); if (ptr != NULL) { pc->data = ptr; pc->capacity += DEFAULT_INC; printf("增容成功"); } else { perror("扩容失败"); return; } } } void AddContact(Contact* pc) { assert(pc); CheckCapacity(pc); printf("请输入名字:>\n"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:>\n"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:>\n"); scanf("%s", (pc->data[pc->sz].sex)); printf("请输入电话:>\n"); scanf("%s", (pc->data[pc->sz].tele)); printf("请输入地址:>\n"); scanf("%s", (pc->data[pc->sz].addr)); pc->sz++; printf("增加成功\n"); }
2.3 销毁空间
接下来我们对开辟的空间进行销毁,本质上就是对指针置空,释放空间即可.
void DestoryContact(Contact* pc) { free(pc->data); pc->capacity = 0; pc->sz = 0; pc->data = NULL; }