通讯录(C 语言)
目录
- 一、通讯录设计思路
- 1. 伪代码设计思路
- 2. 代码设计思路
- 二、代码实现
- 三、程序运行演示
- 四、整体分析
一、通讯录设计思路
1. 伪代码设计思路
通讯录可以用来存储 100 个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址。
提供方法:
- 添加联系人信息
- 删除指定联系人信息
- 查找指定联系人信息
- 修改指定联系人信息
- 显示所有联系人信息
- 清空所有联系人
- 以名字排序所有联系人
2. 代码设计思路
通过对上述伪代码的分析,我们使用结构体 info_person 来表示个人信息。
// 个人信息结构声明
typedef struct info_person
{char name[20]; // 姓名char sex[5]; // 性别size_t age; // 年龄char phone[12]; // 电话char address[40]; // 住址
}info_person;
接着再使用一个结构体 ContacksList 来表示通讯录,该通讯录包含一个结构体 info_person 数组,大小为 100,用来存储 100 个人的信息。此外还应该包含一个 size_t 类型的成员 size 用来表示当前存储个人信息的数量,这也方便了上述伪代码中要求的方法设计。
// 常量声明
#define SIZE_INFO 100// 通讯录结构声明
typedef struct ContacksList
{info_person infos[SIZE_INFO];size_t size;
}ContacksList;
下面就是使用有意义的函数名来表示上述方法。
// 方法// 1. 添加联系人信息
void AddContack(ContacksList* cl);// 2. 删除指定联系人信息
void DeleteContack(ContacksList* cl, char* name);// 3. 查找指定联系人信息
void FindContack(const ContacksList* cl, char* name);// 4. 修改指定联系人信息
void ModifyContack(ContacksList* cl, char* name);// 5. 显示所有联系人信息
void PrintContack(const ContacksList* cl);// 6. 清空所有联系人
void ClearContack(ContacksList* cl);// 7. 以名字排序所有联系人
void SortByName(ContacksList* cl);
以上就是头文件 ContacksList.h 包含的基本内容,剩下的就是方法的实现和代码的测试。
二、代码实现
整体代码分成三个文件:头文件 ContacksList.h,方法定义文件 ContacksList.c,测试文件 test.c。由于头文件在前面已经给出,下面就只给出剩下两个文件。
方法定义文件 ContacksList.c
// 头文件
#include "ContacksList.h"
#include <assert.h>
#include <string.h>// 方法// 1. 添加联系人信息
void AddContack(ContacksList* cl)
{assert(cl);// 通讯录已满if (CAPACITY == cl->size){printf("通讯录已满,添加失败!\n");return;}// 添加// // 输入联系人的相关信息info_person tmp;printf("请输入联系人的信息->");printf("姓名: ");scanf("%s", tmp.name);printf("性别: ");scanf("%s", tmp.sex);printf("年龄: ");scanf("%zd", &tmp.age);printf("电话: ");scanf("%s", tmp.phone);printf("地址: ");scanf("%s", tmp.address);// 拷贝cl->infos[cl->size] = tmp;// 人数 +1++cl->size;printf("添加成功!\n");
}// 2. 删除指定联系人信息
void DeleteContack(ContacksList* cl)
{assert(cl);// 删除//// 查找指定联系人char name[20];printf("请输入删除人的姓名: ");scanf("%s", name);int i = FindContack(cl, name);// 找到了if (-1 != i){// 把该位置往后的联系人往前移while (i < cl->size - 1){// 前移cl->infos[i] = cl->infos[i + 1];// 下一个++i;}// 联系人 -1--cl->size;printf("删除成功!\n");}else{printf("删除失败!\n");}
}// 3. 查找指定联系人信息
int FindContack(const ContacksList* cl, char* name)
{assert(cl);// 通讯录为空if (0 == cl->size)return -1;// 输入查找人的姓名char tmp[20] = { 0 };if (NULL == name){name = tmp;printf("请输入查找人的姓名: ");scanf("%s", name);}// 查找int i;for (i = 0; i < cl->size; ++i){// 找到if (strcmp(cl->infos[i].name, name) == 0){return i;}}// 没找到return -1;
}// 4. 修改指定联系人信息
void ModifyContack(ContacksList* cl)
{assert(cl);// 查找指定联系人char name[20];printf("请输入修改人的姓名: ");scanf("%s", name);int i = FindContack(cl, name);// 找到了if (-1 != i){// 输入联系人修改后的相关信息info_person tmp;printf("请输入联系人的信息->");printf("姓名: ");scanf("%s", tmp.name);printf("性别: ");scanf("%s", tmp.sex);printf("年龄: ");scanf("%zd", &tmp.age);printf("电话: ");scanf("%s", tmp.phone);printf("地址: ");scanf("%s", tmp.address);// 修改cl->infos[i] = tmp;printf("修改成功!\n");}else{printf("修改失败!\n");}
}// 5. 显示所有联系人信息
void PrintContack(const ContacksList* cl)
{assert(cl);// 标题行printf("%-10s%-8s%-8s%-15s%-10s\n", "姓名", "性别", "年龄", "电话", "地址");// 输出int i;for (i = 0; i < cl->size; ++i){printf("%-10s%-8s%-8zd%-15s%-10s\n", cl->infos[i].name, cl->infos[i].sex, cl->infos[i].age, cl->infos[i].phone, cl->infos[i].address);}
}// 6. 清空所有联系人
void ClearContack(ContacksList* cl)
{assert(cl);// 清空cl->size = 0;
}// 7. 以名字排序所有联系人
void SortByName(ContacksList* cl)
{assert(cl);// 冒泡排序int i;for (i = 0; i < cl->size - 1; ++i){int j;for (j = 0; j < cl->size - 1 - i; ++j){// 相邻比较if (strcmp(cl->infos[j].name, cl->infos[j + 1].name) > 0){// 交换info_person tmp = cl->infos[j];cl->infos[j] = cl->infos[j + 1];cl->infos[j + 1] = tmp;}}}printf("按名字身升序排序成功!\n");
}
测试文件 test.c
// 头文件
#include "ContacksList.h"// 菜单
void menu()
{printf("****************************************************\n");printf("***********1. Add 2. Delete *************\n");printf("***********3. Find 4. Modify *************\n");printf("***********5. Print 6. Clear *************\n");printf("***********7. Sort 0. Exit *************\n");printf("****************************************************\n");
}int main()
{// 创建通讯录ContacksList cl = { {0}, 0 };// 选择操作int select = 0;int i = 0;do{// 菜单menu();// 选择printf("请选择: ");scanf("%d", &select);switch (select){case 1:AddContack(&cl);break;case 2:DeleteContack(&cl);break;case 3:i = FindContack(&cl, NULL);printf("%-10s%-8s%-8s%-15s%-10s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%-10s%-8s%-8zd%-15s%-10s\n", cl.infos[i].name, cl.infos[i].sex, cl.infos[i].age, cl.infos[i].phone, cl.infos[i].address);break;case 4:ModifyContack(&cl);break;case 5:PrintContack(&cl);break;case 6:ClearContack(&cl);break;case 7:SortByName(&cl);break;case 0:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择!\n");break;}} while (select);return 0;
}
三、程序运行演示

四、整体分析
该通讯录是一个静态通讯录,容量是固定的,当数据超出容量时不够存储,当数据少于容量时造成空间的浪费。后面作者会把该通讯录升级为动态通讯录,当容量不够的时候会进行增容。
在方法实现中,删除指定联系人函数 DeleteContack() 和修改指定联系人函数 ModifyContack() 都需要先找到指定的联系人,所以可以稍微修改一下查找指定联系人函数 FindContack(),然后再前面两个函数中调用该函数,这样就减少了代码的冗余。删除操作需要判断通讯录是否为空,插入操作需要判断通讯录是否已满。
当然读者可以自行根据需要进行修改,这里只提供一个大概思路和基础功能的实现。
相关文章:
通讯录(C 语言)
目录 一、通讯录设计思路1. 伪代码设计思路2. 代码设计思路 二、代码实现三、程序运行演示四、整体分析 一、通讯录设计思路 1. 伪代码设计思路 通讯录可以用来存储 100 个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址。 提供方法&#x…...
对比Java和TypeScript中的服务注册和查找机制
文章目录 一、Java中的服务注册和查找二、TypeScript中的服务注册和查找2.1 使用依赖注入(DI)框架2.2 injectable原理2.3 使用TypeScript的反射系统实现依赖注入 三、优缺点分析3.1 Java的ServiceLoader3.2 TypeScript的服务注册和查找 四、结论 在构建大…...
Flutter 主流常用第三方库、插件收集
一、Flutter 学习资料 FlutterFlutter官网Flutter中文网咸鱼技术掘金Flutter专栏 Flutter - Dart中(.)、(..)、(...)语法使用_flutter ...-CSDN博客 Flutter pubspec.yaml 配置文件_flutter yaml配置git-CSDN博客 Flutter 添加 example流程_建flutter 工程 怎么自动有example-C…...
【在Linux世界中追寻伟大的One Piece】多路转接select
目录 1 -> I/O多路转接之select 1.1 -> 初识select 1.2 -> select函数原型 1.3 -> 关于fd_set结构 1.4 -> 关于timeval结构 2 -> 理解select执行过程 2.1 -> Socket就绪条件 2.2 -> select特点 2.3 -> select缺点 3 -> select使用示例…...
补一下 二维 平面直角坐标系 到三维
上一篇帖子写到 二维的平面直角坐标系,是那样的,这次补充一下三维的。首先需要,安装一个包,如下: 然后,把参数输入,输入这个坐标系的参数,如下: 这样就可以输出如下的三…...
如何学习Python编程?
如何学习Python编程? 了解基础概念: 学习Python的基本语法,包括变量、数据类型、运算符等。了解控制结构,如条件语句(if语句)和循环(for和while循环)。 选择学习资源: 在…...
使用EasyExcel实现导出excel文件时生成多级下拉选
前言 公司有个需求本来只涉及到两个下拉选项,后面就想能不能实现多个下拉选,当然我这里说的多个下拉选是联动的,比如省、地市、区县这种。 实现步骤 1、添加EasyExcel的Maven依赖 <dependency><groupId>com.alibaba</group…...
微信小程序 高校教材征订系统
文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 系统分为三个角色,分别是教材科、系教学秘书、教研室主任。系统主要完成功能是教材科要发布教材征订信息&am…...
从0开始的STM32 定时器(I):聊一聊基本定时器
目录 时钟源 控制器 时基单元 关于HAL库如何配置基本定时器 HAL是如何初始化我们的定时器句柄的 HAL_TIM_Base_Init 开始定时 如何处理句柄? 在我们使用STM32解决一些问题的时候,常常会遇到说:我想要以一个周期做一些事情:…...
vue常见题型(1-10)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 2.2双向绑定的原理是什么vue框架采用的是数据双向绑定的方式,由三个重要部分构成2.2.1.ViewModel2.2.2 双向绑定2.2.3.1.编译Compile2.2.3.2.依赖收集 3…...
【SpringBoot】使用注解进行XSS防御
在Spring Boot中,我们可以使用注解的方式来进行XSS防御。注解是一种轻量级的防御手段,它可以在方法或字段级别对输入进行校验,从而防止XSS攻击。 引入相关依赖 maven依赖: <!--JSR-303/JSR-380用于验证的注解 --> <de…...
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目分享——共九套(每套四十题) 岗位——芯片与器件设计工程师 岗位意向——模拟芯片 真题题目分享,完整题目,无答案(共8套) 实习岗位…...
vscode 下载慢的解决方法
下载链接示例:https://az764295.vo.msecnd.net/stable/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/code1.62.3-1637137107amd64.deb 解决方法: 把 az764295.vo.msecnd.net 替换成 vscode.cdn.azure.cn...
STM32ZET6-USART使用
一、原理说明 STM32自带通讯接口 通讯目的 通信方式: 全双工:通信时可以双方同时通信。 半双工:通信时同一时间只能一个设备发送数据,其他设备接收。 单工:只能一个设备发送到另一个设备,例如USART只有…...
es自动补全(仅供自己参考)
elasticssearch提供了CompletionSuggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询效率,对于文档中字段的类型有一些约束: 查询类型必须是:completion 字段内容是多个补全词条形成的数组 P…...
13-综合排序:Function Score Query 优化算分
使用了 function_score 查询来根据某个字段的值对查询结果进行打分。以下是该查询的主要部分: query: 包含了实际执行搜索的部分,在这里包括一个 multi_match 查询。 multi_match:用于在多个字段上执行相同的查询。 query:设置…...
鸿蒙应用App测试-专项测试(DevEco Testing)
注意:大家记得先学通用测试在学专项测试 鸿蒙应用App测试-通用测试-CSDN博客 注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注&am…...
RabbitMQ设置消息过期时间
RabbitMQ设置消息过期时间 1、过期消息(死信)2、设置消息过期的两种方式2.1、设置单条消息的过期时间2.1.1、配置文件application.yml2.1.2、配置类RabbitConfig2.1.3、发送消息业务类service(核心代码)2.1.4、启动类2.1.5、依赖文…...
大数据-209 数据挖掘 机器学习理论 - 梯度下降 梯度下降算法调优
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...
粒子群优化双向深度学习!PSO-BiTCN-BiGRU-Attention多输入单输出回归预测
粒子群优化双向深度学习!PSO-BiTCN-BiGRU-Attention多输入单输出回归预测 目录 粒子群优化双向深度学习!PSO-BiTCN-BiGRU-Attention多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现PSO-BiTCN-BiGRU-Attention粒子…...
保姆级教程:在PVE 8.3上搞定Windows 11和Server 2025的VirtIO驱动安装与优化
PVE 8.3虚拟化环境下的Windows系统性能优化全攻略 在虚拟化技术日益普及的今天,Proxmox VE(PVE)作为开源的虚拟化平台,因其稳定性和灵活性受到众多技术爱好者和企业用户的青睐。然而,许多用户在PVE上部署Windows系统时…...
Z-Image-Turbo-rinaiqiao-huiyewunv实战落地:高校动漫社AI辅助创作工作流搭建
Z-Image-Turbo-rinaiqiao-huiyewunv实战落地:高校动漫社AI辅助创作工作流搭建 1. 项目背景与核心价值 高校动漫社团经常面临创作效率低、人手不足的问题。传统手绘方式需要大量时间,而通用AI绘图工具又难以保持角色一致性。Z-Image Turbo (辉夜大小姐-…...
暗黑破坏神2单机增强神器:PlugY插件全方位使用指南
暗黑破坏神2单机增强神器:PlugY插件全方位使用指南 【免费下载链接】PlugY PlugY, The Survival Kit - Plug-in for Diablo II Lord of Destruction 项目地址: https://gitcode.com/gh_mirrors/pl/PlugY 对于暗黑破坏神2单机玩家而言,有限的储物空…...
终极指南:如何用Captum快速理解PyTorch模型的决策逻辑
终极指南:如何用Captum快速理解PyTorch模型的决策逻辑 【免费下载链接】captum Model interpretability and understanding for PyTorch 项目地址: https://gitcode.com/gh_mirrors/ca/captum 在当今人工智能快速发展的时代,PyTorch已成为深度学习…...
OpenSees数值模拟从入门到进阶:理论、代码与实践
OpenSees数值模拟从入门到进阶:理论、代码与实践 摘要 OpenSees(Open System for Earthquake Engineering Simulation)作为开源的地震工程模拟系统,凭借其强大的非线性分析能力和开放的架构,已成为结构地震响应分析领域的重要工具。本文系统介绍OpenSees数值模拟的基本原…...
AI Agent架构实战教程(非常详细),从被动唤醒到主动守望,收藏这一篇就够了!
在LLM驱动的应用进入深水区后,开发者们发现:即便Agent再聪明,如果它只能停留在“你问我答”的被动模式,就永远无法触达“私人助理”的核心体验。 从OpenAI的ChatGPT Tasks到百度的“心响”产品、腾讯元宝定时任务,行业…...
NoSleep防休眠工具:系统唤醒与持续运行的高效解决方案
NoSleep防休眠工具:系统唤醒与持续运行的高效解决方案 【免费下载链接】NoSleep Lightweight Windows utility to prevent screen locking 项目地址: https://gitcode.com/gh_mirrors/nos/NoSleep 在数字化工作环境中,电脑意外休眠往往导致工作中…...
如何用OpenShamrock打造智能QQ机器人:从零开始的完整指南
如何用OpenShamrock打造智能QQ机器人:从零开始的完整指南 【免费下载链接】OpenShamrock A Bot Framework based on Xposed with OneBot11 项目地址: https://gitcode.com/gh_mirrors/op/OpenShamrock OpenShamrock是一款基于Xposed框架实现的QQ机器人开发工…...
MarkDownload:如何用浏览器扩展解决网页内容保存的三大痛点
MarkDownload:如何用浏览器扩展解决网页内容保存的三大痛点 【免费下载链接】markdownload A Firefox and Google Chrome extension to clip websites and download them into a readable markdown file. 项目地址: https://gitcode.com/gh_mirrors/ma/markdownlo…...
语言的边界,与软件的命运
. GIF文件结构 相比于 WAV 文件的简单粗暴,GIF 的结构要精密得多,因为它天生是为了网络传输而设计的(包含了压缩机制)。 当我们用二进制视角观察 GIF 时,它是由一个个 数据块(Block) 组成的&…...
