基于顺序表的通讯录实现

一、前言

基于已经学过的顺序表,可以实现一个简单的通讯录。

二、通讯录相关头文件

//Contact.h
#pragma once#define NAME_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 20
#define GENDER_MAX 20typedef struct PersonInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PsInFo;//struct SeqList;//前置声明typedef struct SeqList Contact;//对顺序表重命名为通讯录//通讯录的初始化
void ContactInit(Contact* pcon);//通讯录的销毁
void ContactDestroy(Contact* pcon);//添加联系人
void ContactAdd(Contact* pcon);//删除联系人
void ContactDel(Contact* pcon);//查找联系人
void ContactFind(Contact* pcon);//修改联系人
void ContactModify(Contact* pcon);//展示联系人
void ContactShow(Contact* pcon);

上述代码中结构体是我们自己定义的通讯录中联系人的基本信息,通讯录中的联系人就相当于是顺序表中的一个个数据,而通讯录就相当于是顺序表;

至于后面两行代码(前置声明和重命名)需要结合以下代码来理解

//SeqList.h
#pragma once
//顺序表
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//引用通讯录的头文件来对数据类型进行重命名
#include"Contact.h"typedef PsInFo SeqDatatype;typedef struct SeqList
{SeqDatatype* arr;int size;int capacity;
}SL;//初始化顺序表
void SeqInit(SL* ps);
//销毁顺序表
void SeqDestroy(SL* ps);
//顺序表尾插
void SeqPushBack(SL* ps, SeqDatatype x);
//申请空间
void SeqCheckSpace(SL* ps);
//打印顺序表的元素
void SeqPrint(SL* ps);
//顺序表头插
void SeqPushFront(SL* ps, SeqDatatype x);
//顺序表尾删
void SeqPopBack(SL* ps);
//顺序表头删
void SeqPopFront(SL* ps);
//指定位置前插入数据
void SeqInsert(SL* ps, int pos, SeqDatatype x);
//删除指定位置的数据
void SeqErase(SL* ps, int pos);
//寻找数据(以下标的形式返回)
//int SeqFind(SL s, SeqDatatype x);

这是顺序表的头文件,我们为了将联系人PsInFo定义为新的数据类型需要引用Contact.h的头文件,这是因为联系人是在Contact.h中定义的;所以现在回到第一段本文展示的代码中的那两行代码(前置声明和重命名),我们为了让SeqList等同于Contact,需要重命名,但是此时要使用SeqList不能直接包含SeqList.h这个头文件,这时因为头文件不能互相包含,此时我们需要进行前置声明,也就是struct SeqList; 可以直接结合起来写成typedef struct SeqList Contact;

值得注意的是,这里不能写成typedef SL Contact;因为这相当于没有进行前置声明。解释:虽然在顺序表头文件中,typedef strcut SeqList{·······}SL 看似是结构体和SL一起定义的,但实际上是结构体先定义的,也就是说,在这个结构体未定义的时候就使用SL是非法的,在Contact.h中写成typedef SL Contact; 就是遇到了这种错误,所以要进行前置声明,这样就能规避这种问题。

三、通讯录的具体实现

1、初始化

//初始化通讯录
void ContactInit(Contact* pcon)
{assert(pcon);SeqInit(pcon);
}

2、销毁

//通讯录销毁
void ContactDestroy(Contact* pcon)
{assert(pcon);SeqDestroy(pcon);
}

3、添加联系人

//添加联系人
void ContactAdd(Contact* pcon)
{assert(pcon);SeqCheckSpace(pcon);PsInFo info;//定义一个联系人printf("输入联系人姓名:\n");scanf("%s", info.name);printf("输入联系人性别:\n");scanf("%s", info.gender);printf("输入联系人年龄:\n");scanf("%d", &info.age);printf("输入联系人电话:\n");scanf("%s", info.tel);printf("输入联系人地址:\n");scanf("%s", info.addr);SeqPushBack(pcon,info);
}

 把联系人当成顺序表中的数据,先把这个数据赋予确定的数值,在这里相当于是给联系人输入一个个属性(姓名、性别、年龄······),最后进行顺序表尾插的操作;

4、返回联系人下标

int FindByName(Contact* pcon,char name[])
{for (int i = 0; i < pcon->size; i++){if (strcmp(name, pcon->arr[i].name)==0){return i;}}return -1;
}

这个函数是通过姓名比较的方式来返回即将进行一系列操作的联系人的下标 

5、删除联系人

//删除联系人
void ContactDel(Contact* pcon)
{assert(pcon);assert(pcon->size);char name[NAME_MAX];printf("输入要删除的联系人姓名:\n");scanf("%s", name);int rsl=FindByName(pcon,name);if (rsl == -1){printf("你要删除的联系人不存在\n");}else{SeqErase(pcon, rsl);}
}

首先判断这个通讯录里面有没有联系人,没有联系人则断言错误,无法删除。接着要输入一个联系人姓名,再在通过FindByName这个通讯录里面进行遍历看是否有没有这个联系人,如果没有接收到错误的下标,进行不了后续操作;找到了返回这个姓名的联系人的下标,然后使用SeqErase删除这个下标处的联系人;

6、查找联系人

//查找联系人
void ContactFind(Contact* pcon)
{assert(pcon);char name[NAME_MAX];printf("输入要查找的联系人姓名:\n");scanf("%s", name);int rsl = FindByName(pcon, name);if (rsl == -1){printf("你要查找的联系人不存在\n");}else{printf("%s""%s""%s""%s""%s", "姓名 ", "性别 ", "年龄 ", "电话 ", "地址 ");printf("\n");printf("%s ""%s ""%d ""%s ""%s ", pcon->arr[rsl].name, pcon->arr[rsl].gender, pcon->arr[rsl].age, pcon->arr[rsl].tel, pcon->arr[rsl].addr);printf("\n");}
}

查找联系人不同于返回联系人下标,它要展示出所查找的这个联系人的相关信息;

7、修改联系人信息

//修改联系人
void ContactModify(Contact* pcon)
{assert(pcon);char name[NAME_MAX];printf("输入要修改信息的联系人姓名:\n");scanf("%s", name);int rsl = FindByName(pcon, name);if (rsl == -1){printf("你要修改信息的联系人不存在\n");}else{printf("开始输入新的联系人信息\n");printf("输入联系人姓名:\n");scanf("%s", pcon->arr[rsl].name);printf("输入联系人性别:\n");scanf("%s", pcon->arr[rsl].gender);printf("输入联系人年龄:\n");scanf("%d", &pcon->arr[rsl].age);printf("输入联系人电话:\n");scanf("%s", pcon->arr[rsl].tel);printf("输入联系人地址:\n");scanf("%s", pcon->arr[rsl].addr);}
}

同样的,先通过姓名的比较来判断该联系人存不存在,若是有则重新在此联系人下标处出入相关信息;

8、展示联系人

//展示联系人
void ContactShow(Contact* pcon)
{assert(pcon);printf("%s""%s""%s""%s""%s", "姓名 ", "性别 ", "年龄 ", "电话 ", "地址 ");printf("\n");for (int i = 0; i < pcon->size; i++){printf("%s ", pcon->arr[i].name);printf("%s ", pcon->arr[i].gender);printf("%d ", pcon->arr[i].age);printf("%s ", pcon->arr[i].tel);printf("%s ", pcon->arr[i].addr);printf("\n");}
}

通过遍历通讯录来展翅一个一个联系人的相关信息。

四、设置操作面板

#include"Contact.h"
#include"SeqList.h"void menu()
{printf("********** 1.增加联系人**********\n");printf("********** 2.删除联系人**********\n");printf("********** 3.查找联系人**********\n");printf("********** 4.修改联系人**********\n");printf("********** 5.展示联系人**********\n");printf("********** 6.销毁通讯录**********\n");printf("********** 0.退出      **********\n");}
int main()
{menu();Contact con;ContactInit(&con);int option = -1;do{printf("输入操作数:\n");scanf_s("%d", &option);switch (option){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactFind(&con);break;case 4:ContactModify(&con);break;case 5:ContactShow(&con);break;case 6:ContactDestroy(&con);break;case 0:printf("退出\n");return;default:printf("输入错误,重新选择\n");}} while (option);return 0;
}

  


完。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python的招聘数据分析与可视化管理系统-计算机毕业设计源码55218

摘要 随着互联网的迅速发展&#xff0c;招聘数据在规模和复杂性上呈现爆炸式增长&#xff0c;对数据的深入分析和有效可视化成为招聘决策和招聘管理的重要手段。本论文旨在构建一个基于Python的招聘数据分析与可视化管理系统。 该平台以主流招聘平台为数据源&#xff0c;利用Py…

昇思25天学习打卡营第2天|MindSpore快速入门

打卡 目录 打卡 快速入门案例&#xff1a;minist图像数据识别任务 案例任务说明 流程 1 加载并处理数据集 2 模型网络构建与定义 3 模型约束定义 4 模型训练 5 模型保存 6 模型推理 相关参考文档入门理解 MindSpore数据处理引擎 模型网络参数初始化 模型优化器 …

如何选择TikTok菲律宾直播网络?

为了满足用户对于实时互动的需求&#xff0c;TikTok推出了直播功能&#xff0c;让用户能够与粉丝即时交流。本文将探讨如何选择适合的TikTok菲律宾直播网络&#xff0c;并分析OgLive是否是值得信赖的选择。 TikTok菲律宾直播网络面临的挑战 作为全球领先的短视频平台&#xff…

Python + OpenCV 开启图片、写入储存图片

这篇教学会介绍OpenCV 里imread()、imshow()、waitKey() 方法&#xff0c;透过这些方法&#xff0c;在电脑中使用不同的色彩模式开启图片并显示图片。 imread() 开启图片 使用imread() 方法&#xff0c;可以开启图片&#xff0c;imread() 有两个参数&#xff0c;第一个参数为档…

Google Play上架:恶意软件、移动垃圾软件和行为透明度详细解析和解决办法 (一)

近期整理了许多开发者的拒审邮件和内容,也发现了许多问题,今天来说一下关于恶意软件这类拒审的问题。 目标邮件如下: 首先说一下各位小伙伴留言私信的一个方法,提供你的拒审邮件和时间,尽可能的详细,这样会帮助我们的团队了解你们的问题,去帮助小伙伴么解决问题。由于前…

集成学习(一)Bagging

前边学习了&#xff1a;十大集成学习模型&#xff08;简单版&#xff09;-CSDN博客 Bagging又称为“装袋法”&#xff0c;它是所有集成学习方法当中最为著名、最为简单、也最为有效的操作之一。 在Bagging集成当中&#xff0c;我们并行建立多个弱评估器&#xff08;通常是决策…

排序——数据结构与算法 总结8

目录 8.1 排序相关概念 8.2 插入排序 8.2.1 直接插入排序&#xff1a; 8.2.2 折半插入排序&#xff1a; 8.2.3 希尔排序&#xff1a; 8.3 交换排序 8.3.1 冒泡排序&#xff1a; 8.3.2 快速排序&#xff1a; 8.4 选择排序 8.4.1 简单选择排序 8.4.2 堆排序 8.5 归并…

磁盘就是一个超大的Byte数组,操作系统是如何管理的?

磁盘在操作系统的维度看&#xff0c;就是一个“超大的Byte数组”。 那么操作系统是如何对这块“超大的Byte数组”做管理的呢&#xff1f; 我们知道在逻辑上&#xff0c;上帝说是用“文件”的概念来进行管理的。于是&#xff0c;便有了“文件系统”。那么&#xff0c;文件系统…

最新版情侣飞行棋dofm,已解锁高阶私密模式,单身狗务必绕道!(附深夜学习资源)

今天阿星要跟大家聊一款让阿星这个大老爷们儿面红耳赤的神奇游戏——情侣飞行棋。它的神奇之处就在于专为情侣设计&#xff0c;能让情侣之间感情迅速升温&#xff0c;但单身狗们请自觉绕道&#xff0c;不然后果自负哦&#xff01; 打开游戏&#xff0c;界面清新&#xff0c;操…

HTML5使用<progress>进度条、<meter>刻度条

1、<progress>进度条 定义进度信息使用的是 progress 标签。它表示一个任务的完成进度&#xff0c;这个进度可以是不确定的&#xff0c;只是表示进度正在进行&#xff0c;但是不清楚还有多少工作量没有完成&#xff0c;也可以用0到某个最大数字&#xff08;如&#xff1…

vs2022安装qt vs tool

1 缘由 由于工作的需要&#xff0c;要在vs2022上安装qt插件进行开发。依次安装qt&#xff0c;vs2022&#xff0c;在vs2022的扩展管理中安装qt vs tool。 2 遇到困难 问题来了&#xff0c;在qt vs tool的设置qt version中出现问题&#xff0c;设置msvc_64-bit时出现提示“invali…

西安石油大学 课程习题信息管理系统(数据库课设)

主要技术栈 Java Mysql SpringBoot Tomcat HTML CSS JavaScript 该课设必备环境配置教程&#xff1a;&#xff08;参考给出的链接和给出的关键链接&#xff09; JAVA课设必备环境配置 教程 JDK Tomcat配置 IDEA开发环境配置 项目部署参考视频 若依框架 链接数据库格式注…

【中项第三版】系统集成项目管理工程师 | 第 4 章 信息系统架构① | 4.1-4.2

前言 第4章对应的内容选择题和案例分析都会进行考查&#xff0c;这一章节属于技术相关的内容&#xff0c;学习要以教材为准。本章分值预计在4-5分。 目录 4.1 架构基础 4.1.1 指导思想 4.1.2 设计原则 4.1.3 建设目标 4.1.4 总体框架 4.2 系统架构 4.2.1 架构定义 4.…

Invoice OCR

Invoice OCR 发票识别 其他类型ORC&#xff1a; DIPS_YTPC OCR-CSDN博客

25款404网页源码(上)

25款404网页源码&#xff08;上&#xff09; 1部分源码 2部分源码 3部分源码 4部分源码 5部分源码 6部分源码 7部分源码 8部分源码 9部分源码 10部分源码 11部分源码 12部分源码 领取完整源码下期更新 1 部分源码 <!DOCTYPE html> <html><!-- 优选源码 gulang.…

数据结构基础--------【二叉树基础】

二叉树基础 二叉树是一种常见的数据结构&#xff0c;由节点组成&#xff0c;每个节点最多有两个子节点&#xff0c;左子节点和右子节点。二叉树可以用来表示许多实际问题&#xff0c;如计算机程序中的表达式、组织结构等。以下是一些二叉树的概念&#xff1a; 二叉树的深度&a…

Element-UI - el-table中自定义图片悬浮弹框 - 位置优化

该篇为前一篇“Element-UI - 解决el-table中图片悬浮被遮挡问题”的优化升级部分&#xff0c;解决当图片位于页面底部时&#xff0c;显示不全问题优化。 Vue.directive钩子函数已在上一篇中详细介绍&#xff0c;不清楚的朋友可以翻看上一篇&#xff0c; “Element-UI - 解决el-…

深入刨析Redis存储技术设计艺术(二)

三、Redis主存储 3.1、存储相关结构体 redisServer:服务器 server.h struct redisServer { /* General */ pid_t pid; /* Main process pid. */ pthread_t main_thread_id; /* Main thread id */ char *configfile; /* Absolut…

Interpretability 与 Explainability 机器学习

「AI秘籍」系列课程&#xff1a; 人工智能应用数学基础人工智能Python基础人工智能基础核心知识人工智能BI核心知识人工智能CV核心知识 Interpretability 模型和 Explainability 模型之间的区别以及为什么它可能不那么重要 当你第一次深入可解释机器学习领域时&#xff0c;你会…

ubuntu 22 安装 lua 环境 编译lua cjson 模块

在 windows 下使用 cygwin 编译 lua 和 cjson 简直就是灾难&#xff0c;最后还是到 ubuntu 下完成了。 1、下载lua源码&#xff08;我下载的 5.1 版本&#xff0c;后面还有一个小插曲), 直接解压编译&#xff0c;遇到一个 readline.h not found 的问题&#xff0c;需要安装 re…