在静态版中,我们使用#define定义了一个标识符常量MAX表示存储联系人的个数。
在动态版通讯录中,通讯录存储联系人的个数是可以改变的,我们使用动态内存开辟,定义通讯录结构体类型,结构体成员包括指向动态开辟内存的指针,通讯录中现有联系人的个数,以及当前通讯录的容量
通讯录结构体声明如下:
//动态版通讯录 struct Contact { struct PeopleInfo* data; //通讯录中当前联系人个数 int sz; //当前总容量 int capacity; };
创建通讯录结构体变量后,要进行初始化操作,这里,我们规定,通讯录最开始可以存储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; }
与静态版通讯录相比,动态版通讯录在增加联系人时,每次都要检测通讯录是否满了,并在通讯录满了之后,使用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)++; }
在程序退出之前,释放动态开辟的空间,销毁通讯录
函数实现如下:
void DestoryContact(struct Contact* con) { //释放动态开辟的空间 free(con->data); con->data = NULL; con->sz = 0; con->capacity = 0; }
其他函数实现与静态版通讯录相同,这里附上动态版通讯录完整的代码:点这里
本章完。