当前位置: 首页 > news >正文

通讯录(C 语言)

目录

  • 一、通讯录设计思路
    • 1. 伪代码设计思路
    • 2. 代码设计思路
  • 二、代码实现
  • 三、程序运行演示
  • 四、整体分析

一、通讯录设计思路

1. 伪代码设计思路

通讯录可以用来存储 100 个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址。

提供方法:

  1. 添加联系人信息
  2. 删除指定联系人信息
  3. 查找指定联系人信息
  4. 修改指定联系人信息
  5. 显示所有联系人信息
  6. 清空所有联系人
  7. 以名字排序所有联系人

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 个人的信息&#xff0c;每个人的信息包括&#xff1a;姓名、性别、年龄、电话、住址。 提供方法&#x…...

对比Java和TypeScript中的服务注册和查找机制

文章目录 一、Java中的服务注册和查找二、TypeScript中的服务注册和查找2.1 使用依赖注入&#xff08;DI&#xff09;框架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使用示例…...

补一下 二维 平面直角坐标系 到三维

上一篇帖子写到 二维的平面直角坐标系&#xff0c;是那样的&#xff0c;这次补充一下三维的。首先需要&#xff0c;安装一个包&#xff0c;如下&#xff1a; 然后&#xff0c;把参数输入&#xff0c;输入这个坐标系的参数&#xff0c;如下&#xff1a; 这样就可以输出如下的三…...

如何学习Python编程?

如何学习Python编程&#xff1f; 了解基础概念&#xff1a; 学习Python的基本语法&#xff0c;包括变量、数据类型、运算符等。了解控制结构&#xff0c;如条件语句&#xff08;if语句&#xff09;和循环&#xff08;for和while循环&#xff09;。 选择学习资源&#xff1a; 在…...

使用EasyExcel实现导出excel文件时生成多级下拉选

前言 公司有个需求本来只涉及到两个下拉选项&#xff0c;后面就想能不能实现多个下拉选&#xff0c;当然我这里说的多个下拉选是联动的&#xff0c;比如省、地市、区县这种。 实现步骤 1、添加EasyExcel的Maven依赖 <dependency><groupId>com.alibaba</group…...

微信小程序 高校教材征订系统

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 系统分为三个角色&#xff0c;分别是教材科、系教学秘书、教研室主任。系统主要完成功能是教材科要发布教材征订信息&am…...

从0开始的STM32 定时器(I):聊一聊基本定时器

目录 时钟源 控制器 时基单元 关于HAL库如何配置基本定时器 HAL是如何初始化我们的定时器句柄的 HAL_TIM_Base_Init 开始定时 如何处理句柄&#xff1f; 在我们使用STM32解决一些问题的时候&#xff0c;常常会遇到说&#xff1a;我想要以一个周期做一些事情&#xff1a;…...

vue常见题型(1-10)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 2.2双向绑定的原理是什么vue框架采用的是数据双向绑定的方式&#xff0c;由三个重要部分构成2.2.1.ViewModel2.2.2 双向绑定2.2.3.1.编译Compile2.2.3.2.依赖收集 3…...

【SpringBoot】使用注解进行XSS防御

在Spring Boot中&#xff0c;我们可以使用注解的方式来进行XSS防御。注解是一种轻量级的防御手段&#xff0c;它可以在方法或字段级别对输入进行校验&#xff0c;从而防止XSS攻击。 引入相关依赖 maven依赖&#xff1a; <!--JSR-303/JSR-380用于验证的注解 --> <de…...

华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)

华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目分享——共九套&#xff08;每套四十题&#xff09; 岗位——芯片与器件设计工程师 岗位意向——模拟芯片 真题题目分享&#xff0c;完整题目&#xff0c;无答案&#xff08;共8套&#xff09; 实习岗位…...

vscode 下载慢的解决方法

下载链接示例&#xff1a;https://az764295.vo.msecnd.net/stable/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/code1.62.3-1637137107amd64.deb 解决方法&#xff1a; 把 az764295.vo.msecnd.net 替换成 vscode.cdn.azure.cn...

STM32ZET6-USART使用

一、原理说明 STM32自带通讯接口 通讯目的 通信方式&#xff1a; 全双工&#xff1a;通信时可以双方同时通信。 半双工&#xff1a;通信时同一时间只能一个设备发送数据&#xff0c;其他设备接收。 单工&#xff1a;只能一个设备发送到另一个设备&#xff0c;例如USART只有…...

es自动补全(仅供自己参考)

elasticssearch提供了CompletionSuggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询效率&#xff0c;对于文档中字段的类型有一些约束&#xff1a; 查询类型必须是&#xff1a;completion 字段内容是多个补全词条形成的数组 P…...

13-综合排序:Function Score Query 优化算分

使用了 function_score 查询来根据某个字段的值对查询结果进行打分。以下是该查询的主要部分&#xff1a; query: 包含了实际执行搜索的部分&#xff0c;在这里包括一个 multi_match 查询。 multi_match&#xff1a;用于在多个字段上执行相同的查询。 query&#xff1a;设置…...

鸿蒙应用App测试-专项测试(DevEco Testing)

注意&#xff1a;大家记得先学通用测试在学专项测试 鸿蒙应用App测试-通用测试-CSDN博客 注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&am…...

RabbitMQ设置消息过期时间

RabbitMQ设置消息过期时间 1、过期消息&#xff08;死信&#xff09;2、设置消息过期的两种方式2.1、设置单条消息的过期时间2.1.1、配置文件application.yml2.1.2、配置类RabbitConfig2.1.3、发送消息业务类service&#xff08;核心代码&#xff09;2.1.4、启动类2.1.5、依赖文…...

大数据-209 数据挖掘 机器学习理论 - 梯度下降 梯度下降算法调优

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

粒子群优化双向深度学习!PSO-BiTCN-BiGRU-Attention多输入单输出回归预测

粒子群优化双向深度学习&#xff01;PSO-BiTCN-BiGRU-Attention多输入单输出回归预测 目录 粒子群优化双向深度学习&#xff01;PSO-BiTCN-BiGRU-Attention多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现PSO-BiTCN-BiGRU-Attention粒子…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...