文章目录
在“静态版通讯录”一章中,我们实现了一个静态版本的通讯录,所谓静态版就是通讯录中数组存储联系人的大小是固定的,如果我们并不需要有那么多的联系人,就造成内存的严重浪费,所以在本章,我们来实现一个动态版的通讯录,能存储联系人的个数可以根据需要改变。
与静态版的区别
1.通讯录结构体声明
在静态版中,我们使用#define定义了一个标识符常量MAX表示存储联系人的个数。
在动态版通讯录中,通讯录存储联系人的个数是可以改变的,我们使用动态内存开辟,定义通讯录结构体类型,结构体成员包括指向动态开辟内存的指针,通讯录中现有联系人的个数,以及当前通讯录的容量
通讯录结构体声明如下:
//动态版通讯录
struct Contact
{
struct PeopleInfo* data;
//通讯录中当前联系人个数
int sz;
//当前总容量
int capacity;
};
2.初始化函数
创建通讯录结构体变量后,要进行初始化操作,这里,我们规定,通讯录最开始可以存储3个联系人的信息,每当通讯录中人数满了,就扩容,扩大为原来的两倍
#define定义标识符常量DEFAULT_SIZE,表示通讯录中能够存储联系人个数的初始值
#define DEFAULT_SIZE 3
初始化函数实现如下:
void InitContact(struct Contact* con)
{
//没有联系人信息
con->sz = 0;
//动态开辟内存
con->data = (struct PeopleInfo*)calloc(DEFAULT_SIZE,sizeof(struct PeopleInfo));
if (con->data == NULL)
{
printf("开辟空间失败!\n");
return -1;
}
con->capacity = DEFAULT_SIZE;
}
3.增加联系人
与静态版通讯录相比,动态版通讯录在增加联系人时,每次都要检测通讯录是否满了,并在通讯录满了之后,使用realloc函数进行扩容
函数实现如下:
void AddContact(struct Contact* con)
{
if (con->sz == con->capacity)
{
//扩容
struct PeopleInfo* ptr= (struct PeopleInfo*)realloc(con->data,2 * (con->sz) * sizeof(struct PeopleInfo));
if (ptr != NULL)
{
//扩容成功
con->data = ptr;
printf("增容成功!\n");
con->capacity *= 2;
}
else
{
//扩容失败
return;
}
}
//录入联系人信息
printf("请输入姓名:>");
scanf("%s", con->data[con->sz].name);
printf("请输入年龄:>");
scanf("%d", &(con->data[con->sz].age));
printf("请输入性别:>");
scanf("%s", con->data[con->sz].sex);
printf("请输入电话:>");
scanf("%s", con->data[con->sz].tele);
printf("请输入地址:>");
scanf("%s", con->data[con->sz].addr);
printf("添加成功!\n");
(con->sz)++;
}
4.释放动态内存空间
在程序退出之前,释放动态开辟的空间,销毁通讯录
函数实现如下:
void DestoryContact(struct Contact* con)
{
//释放动态开辟的空间
free(con->data);
con->data = NULL;
con->sz = 0;
con->capacity = 0;
}
完整代码
其他函数实现与静态版通讯录相同,这里附上动态版通讯录完整的代码:点这里
本章完。