通讯录的改进
一、动态内存+通讯录的实现=高级通讯录的实现
1.整体思想还是通讯录实现的思想是一样的,只是在一开始创建结构体(也就是我的通讯录的空间大小的时候),我不需要直接创建一个1000个成员信息大小的空间,我可以通过动态内存的使用,来让我有几个成员信息需要录入,我就开辟对应的内存来储存,这样就可以大大节省我的内存
2.所以在整体的通讯录的使用中,并不会影响我的几大功能(例:查找功能,删除功能,清除功能和排序等功能),其实本质上只会影响我的添加功能和初始化的功能
3.所以我们接下来就通过代码来看一下是如何使用动态内存来进行对我的初始化功能和好友信息添加功能的一个改变
(1.)初始化函数的改变:
//这边首先默认我们可以存放3个人的信息(这个多少都一样) //当每次发现当前通讯录满了的时候就会进行扩容,并且每次扩容2个空间 void InitContact(struct Contact* ps) { //memset(ps->data, 0);//初始化千万要记得用memset函数 //但是按照此时的这个思路我这个数据的内存并不需要里面都是0,而是想在这个数据中默认可以放3个好友信息的内存 //所以我应该这样写(通过用malloc来开辟动态内存) ps->data = (struct Peoinfor*)malloc(3 * sizeof(struct Peoinfor)); if (ps->data != NULL) { ps->num = 0;//你是人才,真的敢写,这边初始化敢这样写,会死哦 ps->capacity = 3; } }
1.这个功能总的来说就是把memset(ps->data, 0, sizeof(ps->data));原来这句代码改成了这个代码而已 ps->data = (struct Peoinfor*)malloc(3 * sizeof(struct Peoinfor));
2.意思就是我原来的时候已经拥有了存放1000个好友信息的内存,只是内存中还没有好友信息而已,所以我可以把这个空间先给初始化为0,,然而现在我使用了动态内存(并且此时我首先默认我的这个内存中可以放3个好友信息的内存,如果之后内存不够,我就使用动态内存的方式对其进行每次加2的扩容操作),所以首先我们就可以使用malloc这个函数对其开辟3个好友信息大小的动态内存然后再进行扩容操作时,就可以使用realloc这个函数对其进行扩容,这样我就可以实现动态调整我的通讯录的大小了
(2.)增添函数的改变;
代码如下:
void AddContact(struct Contact* ps) { CheckContact(ps);//CheckContact(ps->data);这步错了,还是没有完全理解.检测的就是ps指向的这个通讯录的容量,所以这边应该写成ps printf("请输入你所要增添的信息\n"); printf("请输入好友姓名:"); scanf("%s", ps->data[ps->num].name); printf("请输入好友电话:"); scanf("%s", ps->data[ps->num].tele); printf("请输入好友id:"); scanf("%s", ps->data[ps->num].id); printf("请输入好友住址:"); scanf("%s", ps->data[ps->num].add); printf("请输入好友性别:"); scanf("%s", ps->data[ps->num].sex); printf("请输入好友年龄:"); scanf("%d", &(ps->data[ps->num].age)); ps->num++; printf("输入成功\n"); }
1.总的来看就是把可以进行输入的那个 if 语句判断通讯录是否满了的条件给改成了一个检查通讯录的函数,剩下的都是一个道理
2.所以接下来讲一下这个CheckContact(ps);函数的实现,这个函数的实现就是整个动态开辟通讯录最重要的一个点了
代码如下:
void CheckContact(struct Contact* ps) { if (ps->num == ps->capacity) { printf("空间不足,需要增容\n"); struct Peoinfor* ptr = (struct Peoinfor*)realloc(ps->data, (ps->capacity + 2) * sizeof(struct Peoinfor));//注意realloc的这个使用的意思是增加到,不是增加多少,所以你想变大就一定要把以前的那块空间也算上,不然就出问题 if (ptr != NULL) { ps->data = ptr; printf("增容成功\n"); } } else { printf("增容失败\n"); } }
if (ps->num == ps->capacity)这句就表示我的通讯录已经满了,所以此时要进行扩容了
struct Peoinfor* ptr = (struct Peoinfor*)realloc(ps->data, (ps->capacity + 2) * sizeof(struct Peoinfor));
上面这句代码就是表示扩容,关键就是如何理解realloc的使用(注意realloc的这个使用的意思是增加到多少,不是增加多少,所以你想变大就一定要把以前的那块空间也算上,不然就出问题)
所以这就是对通讯录进行的一系列的动态开辟内存的改进
(3.)所以总的代码如下(不包括多种功能和各种细节处理)
//例:现在对我的初始话功能的改进 #include<stdio.h> #include<stdlib.h> struct Peoinfor { char name[20]; char tele[12]; char id[20]; char add[20]; char sex[5]; int age; }; struct Contact { struct Peoinfor* data;//关键就在于这个指针(原理就在于这个指针指向的空间是可以被调整的)(指针指向的是一个动态内存开辟的内存) int num; //这个是用来判断我当前通讯录中的好友信息的数量的,但是并不会对容量就行判断,所以此时我就一定要有一个变量对容量进行判断 int capacity;//这个东西就是用来判断我当前的容量是否满了(就是代表我此时通讯录的最大容量) }; //这边首先默认我们可以存放3个人的信息(这个多少都一样) //当每次发现当前通讯录满了的时候就会进行扩容,并且每次扩容2个空间 void InitContact(struct Contact* ps) { //memset(ps->data, 0);//初始化千万要记得用memset函数 //但是按照此时的这个思路我这个数据的内存并不需要里面都是0,而是想在这个数据中默认可以放3个好友信息的内存 //所以我应该这样写(通过用malloc来开辟动态内存) ps->data = (struct Peoinfor*)malloc(3 * sizeof(struct Peoinfor)); if (ps->data != NULL) { ps->num = 0;//你是人才,真的敢写,这边初始化敢这样写,会死哦 ps->capacity = 3; } } void CheckContact(struct Contact* ps) { if (ps->num == ps->capacity) { printf("空间不足,需要增容\n"); struct Peoinfor* ptr = (struct Peoinfor*)realloc(ps->data, (ps->capacity + 2) * sizeof(struct Peoinfor));//注意realloc的这个使用的意思是增加到,不是增加多少,所以你想变大就一定要把以前的那块空间也算上,不然就出问题 if (ptr != NULL) { ps->data = ptr; printf("增容成功\n"); } } else { printf("增容失败\n"); } } void AddContact(struct Contact* ps) { CheckContact(ps);//CheckContact(ps->data);这步错了,还是没有完全理解.检测的就是ps指向的这个通讯录的容量,所以这边应该写成ps printf("请输入你所要增添的信息\n"); printf("请输入好友姓名:"); scanf("%s", ps->data[ps->num].name); printf("请输入好友电话:"); scanf("%s", ps->data[ps->num].tele); printf("请输入好友id:"); scanf("%s", ps->data[ps->num].id); printf("请输入好友住址:"); scanf("%s", ps->data[ps->num].add); printf("请输入好友性别:"); scanf("%s", ps->data[ps->num].sex); printf("请输入好友年龄:"); scanf("%d", &(ps->data[ps->num].age)); ps->num++; printf("输入成功\n"); } void DestroyContact(struct Contact* ps) { free(ps->data); ps->data = NULL; } int main() { int input = 0; struct Contact con;//所以此时这个con中就有3个变量(data指针、num、capacity) InitContact(&con); do { printf("请选择你要使用的功能:\n"); scanf("%d", &input); switch (input) { case 1: break; case 2: AddContact(&con); break; case 0: DestroyContact(&con); printf("退出程序\n"); break; default: printf("输入有误\n"); //剩下的功能省略 } } while (input); return 0; }
1.如果想加上功能也是一样的你就一个一个函数去实现就行,不会就适当看一下前面的代码
(4.)总结
学到的东西是可以进行联合使用的,学以致用很关键,虽然我也不会,哈哈哈,乐观