用结构体实现通讯录(动态实现)

简介: 🌸通讯录的需求🌸通讯录的功能🐰 通讯录的原码 🌸主函数🌸头文件🌸函数实现文件

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🌸通讯录的需求

🌸通讯录的功能

🐰 通讯录的原码

🌸主函数

🌸头文件

🌸函数实现文件


🌸通讯录的需求

1.人员的姓名

2.人员的年龄

3.人员的性别

4.人员的电话号码

5.人员的地址

实现方法:通讯录初始设置data_max(我这里设置3)个人的空间,开辟data_max个人的空间,动态创建(使用malloc)data_max个人的空间。我们设置两个结构体,一个保存通讯录的需求,一个保存结构体结构体动态创建的空间,通讯录的人数和通讯录最大容量。

🌸通讯录的功能

相较于静态的通讯录,我们改变了初始化通讯录,增加联系人的功能,添加了判断通讯录空间是否足够的函数,通讯录清空的功能。所以我只大家介绍改变的和新增的功能及函数

初始化通讯录:

1. //动态版本的初始化
2. void InitContact(Contact* pc)
3. {
4.     pc->data=(PeoInfo*)malloc(sizeof(PeoInfo)*data_max);//最开始给通讯录开辟data_max个空间
5.     if(pc->data==NULL)
6.     {
7.         printf("开辟空间失败:%s\n",strerror(errno));
8.         return ;
9.     }
10.     pc->sz=0;
11.     pc->capacity=data_max;//容量最大空间当然也是data_max
12. }

初始化时,最开始给通讯录动态开辟data_max个空间,如果开辟空间失败时,打印出开辟空间失败的原因,开辟成功,将联系人的个数置为0,通讯录的空间置为data_max。

判断通讯录空间是否足够:

1. int CheckCapacity(Contact* pc)
2. {
3. if(pc->sz==pc->capacity)
4.     {
5.         PeoInfo* ptr=(PeoInfo*)realloc(pc->data,sizeof(pc->capacity)*2);
6. if(ptr==NULL)
7.         {
8. printf("增容失败:%s\n",strerror(errno));
9. return 0;
10.         }
11. else
12.         {
13.             pc->data=ptr;
14.             pc->capacity=pc->capacity*2;
15. printf("增容成功,容量为%d\n",pc->capacity);
16. return 1;
17.         }
18.     }
19. return 1;
20. }

如果联系人的个数等于通讯录的最大空间,则需要给通讯录扩容,这里采用的是扩容为原来空间两倍的方式扩容。如果扩容失败,打印扩容失败的原因。如果扩容成功,将扩容空间的首地址保存下来,将通讯录的最大容量更新为原来的两倍。还有,如果扩容成功或则不需要就返回1,扩容失败就返回0。

增加联系人:

1. void AddContact(Contact* pc)
2. {
3. if(CheckCapacity(pc)==0)
4.     {
5. printf("扩容失败\n");
6. return;
7.     }
8. else
9.     {
10. printf("请输入名字\n");
11. scanf("%s",pc->data[pc->sz].name);
12. printf("请输入年龄\n");
13. scanf("%d",&(pc->data[pc->sz].age));
14. printf("请输入性别\n");
15. scanf("%s",pc->data[pc->sz].sex);
16. printf("请输入电话号码\n");
17. scanf("%s",pc->data[pc->sz].tele);
18. printf("请输入地址\n");
19. scanf("%s",pc->data[pc->sz].addr);
20.         pc->sz++;
21. printf("添加成功\n");
22.     }
23. }

如果通过判断通讯录空间是否足够的函数得到返回值为1,我们就可以添加联系人的信息,如果返回值为0,就结束该进程。

通讯录清空:

1. void DestroyContact(Contact* pc)
2. {
3. free(pc->data);
4.     pc->data=NULL;
5.     pc->sz=0;
6.     pc->capacity=0;
7. printf("清空通讯录...\n");
8. }

因为我们是动态开辟空间去创建的通讯录,所以需要手动去释放这些动态开辟的空间,因为系统在程序结束之前,是不会自动释放在堆使用的空间。这样做的目的也刚好满足清空通讯录的要求。

🐰 通讯录的原码

🌸主函数

1. #include"test.h"
2. void menu(void)
3. {
4. printf("===========================\n");
5. printf("        1.添加,2.删除       \n");
6. printf("        3.查找,4.改动       \n");
7. printf("        5.展示,6.排序       \n");
8. printf("        7.清空,0.退出             \n");
9. printf("===========================\n");
10. }
11. enum Option
12. {
13.     EXIT,
14.     ADD,
15.     DEL,
16.     SEARCH,
17.     MODIFY,
18.     SHOW,
19.     SORT,
20.     DESTROY,
21. };
22. int main()
23. {
24.     Contact con;
25. InitContact(&con);
26. int input=0;
27. int op=0;
28. do
29.     {
30. menu();
31. printf("请选择\n");
32. scanf("%d",&input);
33. switch(input)
34.         {
35. case ADD:
36. AddContact(&con);
37. break;
38. case DEL:
39. DelContact(&con);
40. break;
41. case SEARCH:
42. SearchContact(&con);
43. break;
44. case MODIFY:
45. ModifyContact(&con);
46. break;
47. case SHOW:
48. ShowContact(&con);
49. break;
50. case SORT:
51. printf("请选择排序方法\n");
52. printf("=========================\n");
53. printf("1.按名字排序     2.按年龄排序\n");
54. printf("=========================\n");
55. scanf("%d",&op);
56. SortContact(&con,op);
57. case DESTROY:
58. DestroyContact(&con);
59. break;
60. case EXIT:
61. DestroyContact(&con);
62. printf("退出通讯录\n");
63. break;
64. default:
65. printf("输入错误\n");
66. break;
67.         }
68.     }while(input);
69. }

🌸头文件

1. #ifndef test_h
2. #define test_h
3. #include <stdio.h>
4. #endif /* test_h */
5. 
6. #include<string.h>
7. #include<stdlib.h>
8. #include<errno.h>
9. 
10. #define MAX 100
11. #define MAX_NAME 20
12. #define MAX_SEX 5
13. #define MAX_TELE 12
14. #define MAX_ADDR 30
15. 
16. 
17. #define data_max 3
18. typedef struct PeoInfo
19. {
20. char name[MAX_NAME];
21. int age;
22. char sex[MAX_SEX];
23. char tele[MAX_TELE];
24. char addr[MAX_ADDR];
25. }PeoInfo;
26. 
27. //typedef struct Contact
28. //{
29. //    PeoInfo data[MAX];//存放数据
30. //    int sz;//有效信息的个数
31. //}Contact;
32. 
33. 
34. 
35. //动态的版本
36. //1.默认能够存储3个人的信息
37. //2.不够扩容为原来空间的两倍
38. 
39. typedef struct Contact
40. {
41.     PeoInfo *data;//存放数据
42. int sz;//有效信息的个数
43. int capacity;//通讯录当前最大容量
44. }Contact;
45. 
46. 
47. 
48. 
49. //初始化
50. void InitContact(Contact* pc);
51. //增加指定联系人
52. void AddContact(Contact* pc);
53. //展示联系人的信息
54. void ShowContact(Contact* pc);
55. //删除指定人信息
56. void DelContact(Contact* pc);
57. //查找指定人的信息
58. void SearchContact(Contact* pc);
59. //改变指定人信息
60. void ModifyContact(Contact* pc);
61. //给通讯录的人信息排序
62. void SortContact(Contact* pc,int op);
63. //清空通讯录
64. void DestroyContact(Contact* pc);

🌸函数实现文件

1. #include "test.h"
2. //静态版本的初始化
3. //void InitContact(Contact* pc)
4. //{
5. //    pc->sz=0;
6. //    memset(pc->data,0,sizeof(pc->data));
7. //}
8. //动态版本的初始化
9. void InitContact(Contact* pc)
10. {
11.     pc->data=(PeoInfo*)malloc(sizeof(PeoInfo)*data_max);//最开始给通讯录开辟data_max个空间
12. if(pc->data==NULL)
13.     {
14. printf("开辟空间失败:%s\n",strerror(errno));
15. return ;
16.     }
17.     pc->sz=0;
18.     pc->capacity=data_max;//容量最大空间当然也是data_max
19. }
20. //静态增加人员的信息
21. //void AddContact(Contact* pc)
22. //{
23. //    if(pc->sz==MAX)
24. //    {
25. //        printf("通讯录已满,无法增加\n");
26. //    }
27. //    else
28. //    {
29. //        printf("请输入名字\n");
30. //        scanf("%s",pc->data[pc->sz].name);
31. //        printf("请输入年龄\n");
32. //        scanf("%d",&(pc->data[pc->sz].age));
33. //        printf("请输入性别\n");
34. //        scanf("%s",pc->data[pc->sz].sex);
35. //        printf("请输入电话号码\n");
36. //        scanf("%s",pc->data[pc->sz].tele);
37. //        printf("请输入地址\n");
38. //        scanf("%s",pc->data[pc->sz].addr);
39. //    }
40. //    pc->sz++;
41. //    printf("添加成功\n");
42. //}
43. 
44. //检查是否需要扩容
45. int CheckCapacity(Contact* pc)
46. {
47. if(pc->sz==pc->capacity)
48.     {
49.         PeoInfo* ptr=(PeoInfo*)realloc(pc->data,sizeof(pc->capacity)*2);
50. if(ptr==NULL)
51.         {
52. printf("增容失败:%s\n",strerror(errno));
53. return 0;
54.         }
55. else
56.         {
57.             pc->data=ptr;
58.             pc->capacity=pc->capacity*2;
59. printf("增容成功,容量为%d\n",pc->capacity);
60. return 1;
61.         }
62.     }
63. return 1;
64. }
65. //动态增加人员信息
66. void AddContact(Contact* pc)
67. {
68. if(CheckCapacity(pc)==0)
69.     {
70. printf("扩容失败\n");
71. return;
72.     }
73. else
74.     {
75. printf("请输入名字\n");
76. scanf("%s",pc->data[pc->sz].name);
77. printf("请输入年龄\n");
78. scanf("%d",&(pc->data[pc->sz].age));
79. printf("请输入性别\n");
80. scanf("%s",pc->data[pc->sz].sex);
81. printf("请输入电话号码\n");
82. scanf("%s",pc->data[pc->sz].tele);
83. printf("请输入地址\n");
84. scanf("%s",pc->data[pc->sz].addr);
85.         pc->sz++;
86. printf("添加成功\n");
87.     }
88. }
89. 
90. void ShowContact(Contact* pc)
91. {
92. printf("%-10s %-4s %-5s %-12s %-30s\n","性别","年龄","性别","电话号码","地址");
93. for(int i=0;i<pc->sz;i++)
94.     {
95. printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);
96.     }
97. }
98. int Find_name(Contact* pc,char name[])
99. {
100. int i;
101. int pos=-1;
102. for( i=0;i<pc->sz;i++)
103.     {
104. if(strcmp(name,pc->data[i].name)==0)
105.         {
106.             pos=i;
107. break;
108.         }
109.     }
110. return pos;
111. }
112. void DelContact(Contact* pc)
113. {
114. if(pc->sz==0)
115.     {
116. printf("通讯录为空,无法删除\n");
117.     }
118. //删除
119. //1.找到删除人的位置
120. char name[MAX_NAME];
121. int pos=-1;
122. int i;
123. printf("输入删除人的名字;>\n");
124. scanf("%s",name);
125.     pos=Find_name(pc,name);
126. if(pos==-1)
127.     {
128. printf("要删的人不存在\n");
129.     }
130. else{
131. for(i=pos;i<pc->sz-1;i++)
132.         {
133.             pc->data[i]=pc->data[i+1];
134.         }
135.         pc->sz--;
136. printf("删除成功\n");
137.     }
138. }
139. void SearchContact(Contact* pc)
140. {
141. char name[MAX_NAME];
142. printf("输入查找人的名字;>\n");
143. scanf("%s",name);
144. int pos=-1;
145.     pos=Find_name(pc, name);
146. if(pos==-1)
147.     {
148. printf("查找的人不存在\n");
149.     }
150. else
151.     {
152. printf("%-10s %-4s %-5s %-12s %-30s\n","性别","年龄","性别","电话号码","地址");
153. printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
154.     }
155. }
156. void ModifyContact(Contact* pc)
157. {
158. char name[MAX_NAME];
159. printf("输入修改人的名字;>\n");
160. scanf("%s",name);
161. int pos=-1;
162.     pos=Find_name(pc, name);
163. if(pos==-1)
164.     {
165. printf("修改人信息不存在\n");
166.     }
167. else
168.     {
169. printf("请输入名字\n");
170. scanf("%s",pc->data[pos].name);
171. printf("请输入年龄\n");
172. scanf("%d",&(pc->data[pos].age));
173. printf("请输入性别\n");
174. scanf("%s",pc->data[pos].sex);
175. printf("请输入电话号码\n");
176. scanf("%s",pc->data[pos].tele);
177. printf("请输入地址\n");
178. scanf("%s",pc->data[pos].addr);
179. printf("修改成功\n");
180.     }
181. }
182. int cmp_by_name(const void* e1,const void* e2)
183. {
184. return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
185. }
186. int cmp_by_gae(const void* e1,const void* e2)
187. {
188. return ((PeoInfo*)e1)->age-((PeoInfo*)e2)->age;
189. }
190. void SortContact(Contact* pc,int op)
191. {
192. if(op==1)
193.     {
194. qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_name);
195. printf("排序成功\n");
196.     }
197. if(op==2)
198.     {
199. qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_gae);
200. printf("排序成功\n");
201.     }
202. }
203. void DestroyContact(Contact* pc)
204. {
205. free(pc->data);
206.     pc->data=NULL;
207.     pc->sz=0;
208.     pc->capacity=0;
209. printf("清空通讯录...\n");
210. }

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸

相关文章
|
JavaScript API
vue3手写card组件
vue3手写card组件
343 2
|
XML 安全 前端开发
Spring Security—Spring MVC 整合
Spring Security—Spring MVC 整合
472 1
|
11月前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
295 1
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
编解码 Java
请求参数中文乱码-POST解决方法
请求参数中文乱码-POST解决方法
|
算法 人机交互 vr&ar
VR游戏设计中的用户体验考虑:技术深度解析
【8月更文挑战第24天】VR游戏设计是一个复杂而充满挑战的过程,它要求开发者在视觉体验、交互设计、音效与反馈、用户引导与界面设计以及性能优化等方面进行全面考虑。通过不断探索和实践,我们可以为玩家提供更加沉浸、自然和令人满足的VR游戏体验。随着技术的不断进步和应用场景的不断拓展,VR游戏的未来充满了无限可能。
|
11月前
|
编解码 vr&ar 图形学
Unity下如何实现低延迟的全景RTMP|RTSP流渲染
随着虚拟现实技术的发展,全景视频逐渐成为新的媒体形式。本文详细介绍了如何在Unity中实现低延迟的全景RTMP或RTSP流渲染,包括环境准备、引入依赖、初始化客户端、解码与渲染、优化低延迟等步骤,并提供了具体的代码示例。适用于远程教育、虚拟旅游等实时交互场景。
314 2
|
存储 SQL Java
Java实现关键字模糊查询的高效方法及实践
实现关键字模糊查询的方法有多种,每种方法都有其适用场景。在选择合适的方法时,应考虑实际需求、数据量大小、性能要求等因素。正则表达式适用于处理简单文本或小数据集;数据库模糊查询适用于存储在RDBMS中的数据;而第三方库,则适合需要进行复杂搜索的大型项目。选用合适的工具,可以有效提升搜索功能的性能和用户体验。
285 3
|
Java Docker 微服务
【Java异常】Caused by: java.lang.IllegalArgumentException: method GET must not have a request body
【Java异常】Caused by: java.lang.IllegalArgumentException: method GET must not have a request body
416 1
|
机器学习/深度学习 数据可视化 PyTorch
利用PyTorch实现基于MNIST数据集的手写数字识别
利用PyTorch实现基于MNIST数据集的手写数字识别
382 2