• 【C语言】通讯录的简单实现


    通讯录的内容


    contect.h 

    1. #pragma once
    2. // 包含头文件
    3. #include
    4. #include
    5. #include
    6. #include
    7. // 使用枚举常量定义功能
    8. enum Function
    9. {
    10. quit, // 注意这是逗号,不是分号
    11. save,
    12. addition,
    13. delete,
    14. search,
    15. revise,
    16. sort,
    17. show // 最后一个没有逗号
    18. };
    19. // 人的信息
    20. #define NAME_MAX 20
    21. #define SEX_MAX 5
    22. #define TELE_MAX 12
    23. #define ADDR_MAX 30
    24. typedef struct People_Information
    25. {
    26. char name[NAME_MAX];
    27. int age;
    28. char sex[SEX_MAX];
    29. char tele[TELE_MAX];
    30. char addr[ADDR_MAX];
    31. }People; // 通过typedef将struct People_Informtion定义为了People
    32. // 通讯录
    33. #define DATA_MAX 1000
    34. typedef struct Contact
    35. {
    36. People data[DATA_MAX]; // data数组里面存放的是每个人的信息
    37. int sz; // 用于记录通讯录中有几个人的信息
    38. }Contact; // 通过typedef将struct Contact定义为了Contact
    39. // 函数声明
    40. // 初始化通讯录
    41. void InitContact(Contact* contact);
    42. // 增加个人信息
    43. void AddContact(Contact* contact);
    44. // 显示通讯录
    45. void ShowContact(const Contact* contact);
    46. // 删除指定信息
    47. void DelContact(Contact* contact);
    48. // 查找指定信息
    49. void SeaContact(const Contact* contact);
    50. // 修改指定联系人
    51. void RevContact(Contact* contact);
    52. // 排序通讯录
    53. void SorContact(Contact* contact);

    contact.c 

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include "contact.h"
    3. void menu()
    4. {
    5. printf("..............................\n");
    6. printf("....0:quit........1:save......\n");
    7. printf("....2:addition....3:delete....\n");
    8. printf("....4:search......5:revise....\n");
    9. printf("....6:sort........7:show......\n");
    10. printf("..............................\n");
    11. }
    12. int main()
    13. {
    14. // 利用do{}while();循环和switch语句进行多次选择
    15. int input;
    16. // 进入main函数就要创建通讯录
    17. Contact contact; // contact就是一个通讯录
    18. // 初始化通讯录
    19. InitContact(&contact); // 将通讯录的地址传过去,不仅节省地址,而且可以通过形参改变实参
    20. do
    21. {
    22. // 有哪些功能
    23. // 通过菜单将功能展现出来
    24. menu();
    25. printf("请输入功能序号:");
    26. scanf("%d", &input);
    27. switch (input)
    28. {
    29. // 通过枚举常量定义会更直观
    30. case quit:
    31. printf("退出通讯录!\n");
    32. break;
    33. case save:
    34. break;
    35. case addition:
    36. AddContact(&contact);
    37. break;
    38. case delete:
    39. DelContact(&contact);
    40. break;
    41. case search:
    42. SeaContact(&contact);
    43. break;
    44. case revise:
    45. RevContact(&contact);
    46. break;
    47. case sort:
    48. SorContact(&contact);
    49. break;
    50. case show:
    51. ShowContact(&contact);
    52. break;
    53. default:
    54. printf("无此序号,请重新输入。\n");
    55. }
    56. } while (input);
    57. return 0;
    58. }

    test.c 

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include "contact.h"
    3. // 初始化通讯录
    4. void InitContact(Contact* contact)
    5. {
    6. assert(contact);
    7. // contact->data = 0; // contact->data表示的是首元素地址
    8. // 初始化一块连续的内存空间可以使用memset
    9. memset(contact->data, 0, sizeof(contact->data));
    10. contact->sz = 0;
    11. }
    12. // 增加个人信息
    13. void AddContact(Contact* contact)
    14. {
    15. assert(contact);
    16. // 进入函数进行判断
    17. if (contact->sz == DATA_MAX)
    18. {
    19. printf("通讯录已满,无法增加个人信息!\n");
    20. return;
    21. }
    22. // 没有满则进行增加个人信息
    23. printf("请输入姓名:");
    24. scanf("%s", &(contact->data[contact->sz].name));
    25. printf("请输入年龄:");
    26. scanf("%d", &(contact->data[contact->sz].age));
    27. printf("请输入性别:");
    28. scanf("%s", &(contact->data[contact->sz].sex));
    29. printf("请输入电话:");
    30. scanf("%s", &(contact->data[contact->sz].tele));
    31. printf("请输入地址:");
    32. scanf("%s", &(contact->data[contact->sz].addr));
    33. // 增加完一条信息后sz要加1
    34. contact->sz++;
    35. printf("增加成功!\n");
    36. }
    37. // 显示通讯录
    38. void ShowContact(const Contact* contact)
    39. {
    40. assert(contact);
    41. // 进入函数进行判断
    42. if (contact->sz == 0)
    43. {
    44. printf("通讯录为空!\n");
    45. return;
    46. }
    47. // 显示信息
    48. // 标题
    49. printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "住址");
    50. for (int i = 0; i < contact->sz; i++)
    51. {
    52. printf("%-10s %-5d %-5s %-12s %-30s\n",
    53. contact->data[i].name,
    54. contact->data[i].age,
    55. contact->data[i].sex,
    56. contact->data[i].tele,
    57. contact->data[i].addr
    58. );
    59. }
    60. }
    61. // 通过名字查找联系人下标
    62. int FindByName(const Contact* contact, char* name)
    63. {
    64. assert(contact);
    65. for (int i = 0; i < contact->sz; i++)
    66. {
    67. if (strcmp(contact->data[i].name, name) == 0)
    68. {
    69. // 找到返回数组下标
    70. return i;
    71. }
    72. }
    73. return -1;
    74. }
    75. // 删除指定信息
    76. void DelContact(Contact* contact)
    77. {
    78. assert(contact);
    79. char name[NAME_MAX];
    80. if (contact->sz == 0)
    81. {
    82. printf("通讯录为空!\n");
    83. return;
    84. }
    85. // 通过名字查找
    86. printf("请输入要删除人的姓名:");
    87. scanf("%s", name);
    88. int ret = FindByName(contact, name);
    89. // 没找到
    90. if (ret == -1)
    91. {
    92. printf("要删除的人不存在!\n");
    93. }
    94. // 找到了
    95. // 删除这个人(其实是覆盖)
    96. for (int i = ret; i < contact->sz - 2; i++) //2这里不是很懂
    97. {
    98. contact->data[i] = contact->data[i + 1];
    99. }
    100. contact->sz--;
    101. printf("删除成功!\n");
    102. // 最后一个直接覆盖当前这个
    103. // 结构体类型相同可以直接赋值
    104. /*contact->data[ret] = contact->data[contact->sz];
    105. contact->sz--;*/
    106. }
    107. // 查找指定信息
    108. void SeaContact(const Contact* contact)
    109. {
    110. assert(contact);
    111. char name[NAME_MAX];
    112. if (contact->sz == 0)
    113. {
    114. printf("通讯录为空!\n");
    115. return;
    116. }
    117. // 通过名字查找
    118. printf("请输入要修改人的姓名:");
    119. scanf("%s", name);
    120. int ret = FindByName(contact, name);
    121. // 没找到
    122. if (ret == -1)
    123. {
    124. printf("要查找的人不存在!\n");
    125. }
    126. // 找到了
    127. // 显示出来
    128. printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "住址");
    129. printf("%-10s %-5d %-5s %-12s %-30s\n",
    130. contact->data[ret].name,
    131. contact->data[ret].age,
    132. contact->data[ret].sex,
    133. contact->data[ret].tele,
    134. contact->data[ret].addr
    135. );
    136. }
    137. // 修改指定联系人
    138. void RevContact(Contact* contact)
    139. {
    140. assert(contact);
    141. char name[NAME_MAX];
    142. if (contact->sz == 0)
    143. {
    144. printf("通讯录为空!\n");
    145. return;
    146. }
    147. // 通过名字修改
    148. printf("请输入要修改人的姓名:");
    149. scanf("%s", name);
    150. int ret = FindByName(contact, name);
    151. // 没找到
    152. if (ret == -1)
    153. {
    154. printf("要修改的人不存在!\n");
    155. }
    156. // 找到了
    157. // 修改
    158. printf("请输入姓名:");
    159. scanf("%s", &(contact->data[contact->sz].name));
    160. printf("请输入年龄:");
    161. scanf("%d", &(contact->data[contact->sz].age));
    162. printf("请输入性别:");
    163. scanf("%s", &(contact->data[contact->sz].sex));
    164. printf("请输入电话:");
    165. scanf("%s", &(contact->data[contact->sz].tele));
    166. printf("请输入地址:");
    167. scanf("%s", &(contact->data[contact->sz].addr));
    168. printf("修改成功!\n");
    169. }
    170. int compare_name(const void* x, const void* y)
    171. {
    172. return strcmp((char*)x, (char*)y);
    173. }
    174. // 排序通讯录
    175. void SorContact(Contact* contact)
    176. {
    177. assert(contact);
    178. if (contact->sz == 0)
    179. {
    180. printf("通讯录为空!\n");
    181. return;
    182. }
    183. // 排序通讯录
    184. qsort(contact, contact->sz, sizeof(contact->data[0]), compare_name);
    185. // 显示信息
    186. // 标题
    187. printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "住址");
    188. for (int i = 0; i < contact->sz; i++)
    189. {
    190. printf("%-10s %-5d %-5s %-12s %-30s\n",
    191. contact->data[i].name,
    192. contact->data[i].age,
    193. contact->data[i].sex,
    194. contact->data[i].tele,
    195. contact->data[i].addr
    196. );
    197. }
    198. }

      注意:

    传址还是传值

    通讯录初始化涉及到传递参数,那我们到底是传址还是传值呢?

    InitContact(&contact);  // 传递的是地址

    // 传址:因为更节省内存空间(地址只占4/8个字节),而且可以通过形参来改变实参;

    // 传值:所需的内存空间更大,并且改变形参并不会影响实参;


    memset初始化连续空间

    // 这里使用的是memset初始化数组,也可以通过循环将数组一个一个制成0;

    memset的用法

     


    存在的缺陷

    初始设计的通讯录所存在的缺陷

    1、录入的信息,只要一退出程序,数据就会丢失,因为数据是存放在内存中的;

    解决方案就是:文件存储、数据存储

    2、通讯录开辟的空间是固定的,如果存放的信息多空间就小了;如果存放的信息少空间就大了;

    解决方案就是:动态内存管理

  • 相关阅读:
    前端面试的话术集锦第 9 篇:高频考点(webpack性能优化)
    什么是IDE?新手用哪个IDE比较好?
    docker仓库的搭建以及使用
    otn 709帧结构
    ReactNative封装Android原生模块
    ZCC5429 异步升压芯片
    Day35PHP数组
    【MySQL】就这一篇帮你解决 MySQL 磁盘占用过高的问题
    大连首届“最美品牌文化代言人”启动,汉纳西点发现传播美好
    Python写猜数游戏
  • 原文地址:https://blog.csdn.net/2201_75406088/article/details/133828655