导语
这一片博客我会改进上次的静态+文件通讯录,先分析哪里可以改,然后再下手,最后测试。
先从动态方面开始改。
动态改进
首先是储存联系人的潍坊可以更改,因为你写了100不一定能存上100个位置,这样容易浪费空间,或者是100个不够你还要手动去更改,很麻烦,我们可以让他刚开始分配一小块那日村,不够就一直扩容。
我们这里初始能放3个联系人,不够的话每次加2个。(数量少方便测试)
初始化通讯录与添加联系人的更改
首先,因为动态内存函数的性质,我们需要把结构体:
contacts.h
typedef struct person { char name[20];//名字 int age;//年龄 char sex[20];//性别 char phone[20];//电话 char location[20];//住址 }person; typedef struct contacts { person *data;//存放人信息的位置 int count;//记录通讯录的人数 int capacity;//记录当前通讯录有多少人 }contacts;
存放人信息的位置给更改成指针,然后需要一个变量来统计通讯录的容量。
首先改一下初始化通讯录的函数:
contacts.c
int initialize(contacts* pc) { assert(pc != NULL); pc->count = 0;//将计数的变量初始化为0 pc->data = calloc(3,sizeof(person));//开辟一个动态内存,然后把地址传给data指针 if (pc->data == NULL) { printf("initialize:%s",strerror(errno)); return 1; } pc->capacity = 3;//一开始让通讯录只有三个人的容量 return 0; }
这次改添加联系人的地方
既然是无限扩容,就没有通讯录已满这一说,我们把判断人是不是满给改掉。
当然,把增容的内容封装成一个函数更容易维护:
contacts.c
void capacity_increase(contacts* pc)//增容 { if (pc->count == pc->capacity) { person* str = (person*)realloc(pc->data, sizeof(person) * (pc->capacity + 2)); if (str == NULL) { printf("addcontact:%s", strerror(errno)); return 1; } else { pc->data = str; pc->capacity += 2; } printf("增容成功\n"); } } int addcontact(contacts* pc) { assert(pc != NULL);//断言pc指向的位置不是空指针 capacity_increase(pc);//增容 printf("姓名:"); scanf("%s", pc->data[pc->count].name); printf("年龄:"); scanf("%d", &(pc->data[pc->count].age)); printf("性别:"); scanf("%s", pc->data[pc->count].sex); printf("电话号:"); scanf("%s", pc->data[pc->count].phone); printf("家庭住址:"); scanf("%s", pc->data[pc->count].location); pc->count++; printf("增加成功\n"); }
当然,退出程序的时候也要释放掉开辟的内存,所以写一个销毁内存的函数。
void destroycontact(contacts* pc) { assert(pc != NULL); free(pc->data); pc->data = NULL; }
动态通讯录的完全体
contacts.h
#include <stdio.h> #include <string.h> #include <assert.h> #include <stdlib.h> #define MAX 100//通讯录最大人数 //定义的结构体 typedef struct person { char name[20];//名字 int age;//年龄 char sex[20];//性别 char phone[20];//电话 char location[20];//住址 }person; typedef struct contacts { person* data;//存放人信息的位置 int count;//记录通讯录的人数 int capacity;//记录当前通讯录有多少人 }contacts; //函数声明区 int initialize(contacts* pc);//初始化通讯录 int addcontact(contacts* pc);//输入联系人信息 void showcontact(const contacts* pc);//打印通讯录 int delcontact(contacts* pc);//删除联系人 int modifycontact(contacts* pc);//修改联系人信息 int findcontact(contacts* pc);//查找联系人 void sortcontact(contacts* pc);//排序通讯录 void destroycontact(contacts* pc);//动态内存销毁
contacts.c
#include "contacts.h" int find_out(char* p1, contacts* p2) { assert(p1 != NULL); assert(p2 != NULL); int i = 0; for (i = 0; i < p2->count; i++) { if (!strcmp(p1, p2->data[i].name))//如果相等就返回0,前面加了!操作符,所以非零条件不成立 return i; } return -1; } void capacity_increase(contacts* pc)//增容 { if (pc->count == pc->capacity) { person* str = (person*)realloc(pc->data, sizeof(person) * (pc->capacity + 2)); if (str == NULL) { printf("addcontact:%s", strerror(errno)); return 1; } else { pc->data = str; pc->capacity += 2; } printf("增容成功\n"); } } int initialize(contacts* pc) { assert(pc != NULL); pc->count = 0;//将计数的变量初始化为0 pc->data = (person*)calloc(3,sizeof(person)); if (pc->data == NULL) { printf("initialize:%s",strerror(errno)); return 1; } pc->capacity = 3; return 0; } int addcontact(contacts* pc) { assert(pc != NULL);//断言pc指向的位置不是空指针 capacity_increase(pc);//增容 printf("姓名:"); scanf("%s", pc->data[pc->count].name); printf("年龄:"); scanf("%d", &(pc->data[pc->count].age)); printf("性别:"); scanf("%s", pc->data[pc->count].sex); printf("电话号:"); scanf("%s", pc->data[pc->count].phone); printf("家庭住址:"); scanf("%s", pc->data[pc->count].location); pc->count++; printf("增加成功\n"); } void showcontact(const contacts* pc) { assert(pc != NULL); int i = 0; printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址"); for (i = 0; i < pc->count; i++) { printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].phone, pc->data[i].location); } } int delcontact(contacts* pc) { assert(pc != NULL); char name[20] = { 0 }; printf("输入此人姓名\n"); scanf("%s", name); int i = find_out(name, pc); if (i == -1) { printf("无此人信息\n"); return 1; } pc->count = pc->count - 1; while (i < pc->count) { pc->data[i] = pc->data[i + 1]; i++; } printf("删除成功\n"); } int modifycontact(contacts* pc) { assert(pc != NULL); printf("输入此人姓名\n"); char name[20] = { 0 }; scanf("%s", name); int i = find_out(name, pc); if (i == -1) { printf("无此人信息\n"); return 1; } printf("请输入要修改的信息\n"); printf("姓名:"); scanf("%s", pc->data[i].name); printf("年龄:"); scanf("%d", &(pc->data[i].age)); printf("性别:"); scanf("%s", pc->data[i].sex); printf("电话号:"); scanf("%s", pc->data[i].phone); printf("家庭住址:"); scanf("%s", pc->data[i].location); printf("修改成功\n"); } int findcontact(contacts* pc) { assert(pc != NULL); printf("输入此人姓名\n"); char name[20] = { 0 }; scanf("%s", name); int i = find_out(name, pc); if (i == -1) { printf("无此人信息\n"); return 1; } printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址"); printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].phone, pc->data[i].location); } int estimate(const void* p1, const void* p2) { return strcmp(((person*)p1)->name, ((person*)p2)->name); } void sortcontact(contacts* pc) { assert(pc != NULL); qsort(pc->data, pc->count, sizeof(person), estimate); printf("排序成功\n"); } void destroycontact(contacts* pc) { assert(pc != NULL); free(pc->data); pc->data = NULL; }
test.c
#include "contacts.h" enum list { EXIT, ADD, DEL, MODIFY, FIND, SHOW, SORT }; void catalogue() { printf("*********************************\n"); printf("*** 1.add 2.del ***\n"); printf("*** 3.modify 4.find ***\n"); printf("*** 5.show 6.sort ***\n"); printf("*** 0.exit ***\n"); printf("*********************************\n"); } int main() { int n = 0; contacts con;//通讯录 initialize(&con);//初始换通讯录 do { catalogue();//通讯录菜单 printf("请选择>"); scanf("%d", &n);//选择要做什么 switch (n) { case EXIT://退出程序 destroycontact(&con); printf("退出通讯录\n"); break; case ADD://添加联系人 addcontact(&con); break; case DEL://删除联系人 delcontact(&con); break; case FIND://查找联系人 findcontact(&con); break; case MODIFY://修改联系人信息 modifycontact(&con); break; case SHOW://展示联系人 showcontact(&con); break; case SORT://排序通讯录 sortcontact(&con); break; default: printf("输入错误请重新输入\n"); } } while (n); return 0; }