顺序表的应用——通讯录的实现

前言

本篇博客将接着上次顺序表的内容进行拓展应用,这次来为大家介绍通讯录的实现,它就是基于顺序表的结构完成的;如果你对此感兴趣,请看下面的内容;

1.顺序表的应用

我们前面学过,顺序表可以存放任意类型的元素,前面我们在顺序表中存放整型元素,浮点型元素等内置类型;今天,我们将在顺序表中存放结构体这种自定义类型的变量;生活中,大家都使用过手机的通讯录,通讯录中有联系人的各种信息,那么如果我们想创建一个通讯录,那么我们就需要把每个联系人的不同信息放到一个结构体中,并且将其存放起来,那么就需要用到顺序表这个数据结构了;

OK,上面说了通讯录的基本逻辑,下面开始进行代码实现;

首先,基于顺序表专题的代码,我们需要新创建一个通讯录的头文件和一个通讯录的实现文件;

 

这里我们就创建好了;下面我们需要在头文件中定义联系人数据结构,在这里,我们需要定义联系人的姓名、性别、年龄、电话、地址这五个信息,大家请看下面的代码;

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct personInfo
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;

这里大家可以看到,我们定义了我们需要的数据,并且规定了它们的大小;

下面,我们还需要在顺序表的头文件中。将数据类型进行替换;

typedef peoInfo SLDataType;

下面。我们要对通讯录实行初始化、销毁,增删查改等一系列操作;那么我们需要知道,对通讯录的操作实际上就是对顺序表进行操作;

那么这里我们就需要进行以下操作;

首先,我们要给顺序表改个名字,让它叫作通讯录;

​
typedef SL Contact;​

这里我们就改好了,但是这里大家需要注意一个点,我们必须要在通讯录的头文件中进行前置声明,否则将找不到SL这个结构体;

1.1 通讯录的初始化

首先,我们需要在通讯录头文件中进行方法声明;

void ContactInit(Contact* con);

下面,我们要在通讯录的实现文件中去实现初始化的方法;这里大家注意,上面说了对通讯录的操作就是对顺序表的操作,那么我们只需要引用顺序表初始化的方法就可以实现对通讯录的初始化;这里大家就需要在通讯录的实现文件中包含两个头文件:"Contact.h"  "SeqList.h";然后我们就可以引用顺序表的初始化方法来对通讯录进行初始化了;

void ContactInit(Contact* con)
{SLInit(con);
}

初始化的代码很简单,直接引用顺序表中写好的初始化方法即可。

初始化完成后,我们需要进行测试,这个时候我们需要进行测试;

这里大家在测试的过程中打开调试窗口,监视一下con,你会发现,con实际上就是顺序表,这与我们前面所述一致,我们对通讯录操作实际上就是对顺序表进行操作。

1.2 通讯录的销毁

上面说完了初始化,下面来看通讯录的销毁,操作方法与上面类似;

首先还是要在通讯录的头文件中进行声明;

void ContactDestroy(Contact* con);

声明完后,我们要在“Contact.c”文件中进行方法实现;

void ContactDestroy(Contact* con)
{SLDestroy(con);
}

这里因为我们前面已经写过顺序表的销毁方法了,所以这里直接可以拿来用,代码比较简单。

实现完成后,我们要进行测试,继续在test.c文件中进行测试;

 测试的结果大家可以自行进行调试,这里不做赘述。

1.3 通讯录添加数据

 首先还是先在头文件中声明;

void ContactAdd(Contact* con);

其次我们来进行方法实现;

void ContactAdd(Contact* con)
{peoInfo info;printf("请输入要添加的联系人姓名:\n");scanf("%s", info.name);printf("请输入要添加的联系人性别:\n");scanf("%s", info.gender);printf("请输入要添加的联系人年龄:\n");scanf("%d", &info.age);printf("请输入要添加的联系人电话:\n");scanf("%d", info.tel);printf("请输入要添加的联系人地址:\n");scanf("%d", info.addr);SLPushBack(con, info);
}

这里大家来看代码,我们要将用户输入的信息保存到通讯录中,所以我们需要先用通讯录来创建一个结构体变量,然后进行存储。这里要提醒大家一点,在输入年龄时,我们需要加上&操作符,儿其他的变量都是不需要的,因为大家可以看一开始我们对通讯录的定义,只有年龄是整型变量,其他的都是字符数组,我们知道数组名表示的就是首元素的地址,所以在这里我们输入的格式中不需要加&操作符,这一点希望大家注意一下;最后这里我以尾插为例来进行数据的插入。

下面来进行测试;

 

大家在测试的时候。可以进行调试,监视通讯录中的数据,如上图所示,我们可以发现已经将我们输入的联系人数据存入通讯录。

1.4 通讯录删除数据

上来我们还是先在“Contact.h”中声明方法;

void ContactDel(Contact* con);

下面来实现删除的方法,这里大家思考一下,我们想要删除数据,是不是先要有数据存在,我们才能进行删除,那么我们想要删除指定的信息,就必须得先进行查找;所以这里我们需要引进一个查找的函数,我们以查找姓名为例;

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

这里大家来看这个查找函数,我们用到了strcmp函数来判断两个字符串是否相等,如果返回值为0,那么证明我们找到了对应的姓名信息。

我们继续来实现删除的方法,大家看下面的代码;

 

void ContactDel(Contact* con)
{char name[NAME_MAX];scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要删除的联系人数据不存在\n");return;}SLErase(con, find);printf("删除成功\n");
}

这里我们要根据姓名来查找,所以直接创建一个字符数组即可,然后我们需要调用我们上面刚写的查找函数,如果返回值为负数,证明没有找到(返回的下标,下标不能为负数);如果找到了,这里我们要删除它,那么就需要用在顺序表中定义的方法“在指定位置删除数据”,这样我们就可以成功删除我们想删除的数据。

下面我们在test.c文件中测试一下通讯录的删除;

 大家发现,size变成了0,证明我们删除成功了。

1.5 通讯录的展示

 这里为大家介绍展示通讯录的方法;首先还是声明;

void ContactShow(Contact* con);

然后来进行方法的实现;

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

这里我们要遍历通讯录,将通讯录中的信息打印出来;

下面我们来测试一下;

 

 

 大家可以看到,通讯录中的数据发生了变化,这里比调试看的更直观。

1.6 通讯录的修改

 继续来看通讯录的修改,一上来还是先进行声明;

void ContactModify(Contact* con);

下面再来实现修改的方法,这里大家要注意,要修改数据,前提要保证数据的存在性,所以这里的代码和上面的删除代码就有几分相似了;

这里大家会发现上半部分和删除的代码是一样的,下半部分我们只需要依次输入新的联系人数据即可。

​
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要删除的联系人数据不存在\n");return;}printf("请输入新的姓名 \n");scanf("%s", con->arr[find].name);printf("请输入新的性别 \n");scanf("%s", con->arr[find].gender);printf("请输入新的年龄 \n");scanf("%s", &con->arr[find].age);printf("请输入新的电话 \n");scanf("%s", con->arr[find].tel);printf("请输入新的地址 \n");scanf("%s", con->arr[find].addr);printf("修改成功\n");
}​

下面来测试一下修改的代码;

 

大家可以看到。这里我们完成了修改。

1.7 通讯录的查找 

 还是在头文件中进行声明;

void ContactFind(Contact* con);

然后我们来实现查找方法;

void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要查找的联系人数据不存在\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%s %s %d %s %s\n", con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}

接下来,我们来测试一下;

 

大家可以看到,在我们输入完信息后,我们可以查找到我们对应联系人的所有信息,这里我们的查找功能就成功实现了。

2. 通讯录的整体实现 

 上面已经为大家介绍完通讯录的所有操作了,下面我们要将其加工成一个像样的项目;

void meau()
{printf("************通讯录************\n");printf("**1.增加联系人  2.删除联系人**\n");printf("**3.修改联系人  4.查找联系人**\n");printf("**5.展示联系人  6.退出通讯录**\n");printf("******************************\n");
}
int main()
{int op = -1;Contact con;ContactInit(&con);do{meau();printf("请选择操作: \n");scanf("%d", &op);switch (op){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("通讯录退出\n");break;default :printf("输入错误,请选择正确的选项!\n");break;}} while (op != 0);ContactDestroy(&con);return 0;
}

这里我们增加了一个菜单来供用户选择,下面我们使用了do-while语句来实现循环的效果,还用到了switch语句来实现分支结构,经过这一系列操作,我们完善了通讯录项目。

下面为大家展示完整的代码;

首先,来展示头文件Contact.h 

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct SeqList Contact;
typedef struct personInfo
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);

下面是通讯录的实现文件Contact.c

#include"Contact.h"
#include"Seqlist.h"
void ContactInit(Contact* con)
{SLInit(con);
}
void ContactDestroy(Contact* con)
{SLDestroy(con);
}
void ContactAdd(Contact* con)
{peoInfo 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);SLPushBack(con, info);
}
int FindByName(Contact* con, char name[])
{for (int i = 0;  i< con->size; i++){if (strcmp(con->arr[i].name, name) == 0){return i;}}return -1;
}
void ContactDel(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要删除的联系人数据不存在\n");return;}SLErase(con, find);printf("删除成功! \n");
}
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%s %s %d %s %s\n", con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要删除的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要修改的联系人数据不存在\n");return;}printf("请输入新的姓名 \n");scanf("%s", con->arr[find].name);printf("请输入新的性别 \n");scanf("%s", con->arr[find].gender);printf("请输入新的年龄 \n");scanf("%d", &con->arr[find].age);printf("请输入新的电话 \n");scanf("%s", con->arr[find].tel);printf("请输入新的地址 \n");scanf("%s", con->arr[find].addr);printf("修改成功\n");
}
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要查找的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要查找的联系人数据不存在\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%s %s %d %s %s\n", con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}

最后来看测试文件test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void ContactTest01()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactAdd(&con);ContactShow(&con);//ContactModify(&con);//ContactDel(&con);//ContactShow(&con);ContactFind(&con);ContactDestroy(&con);
}
int main()
{ContactTest01();return 0;
}

这里说明一下,通讯录是顺序表的应用,关于顺序表的相关方法,大家可以在我的另一篇博客《顺序表专题》中看到,这里就不再重复展示。

3. 总结

 本篇博客主要为大家介绍了顺序表这个数据结构的经典运用——通讯录,顺序表是数据结构的基础内容,希望大家理解并掌握顺序表的写法,同时通过通讯录来进一步加深对顺序表的理解。通讯录的本质就是顺序表,只不过套了一个的外壳,叫做了顺序表;最后,希望本篇博客可以为大家带来帮助,谢谢阅读!

 

 

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

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

相关文章

Android Gradle开发与应用Gradle详细使用

一、Gradle 基础知识 1. Gradle 构建脚本 Gradle 构建脚本通常使用 Groovy 或 Kotlin DSL 编写。Android 项目中有两个主要的 Gradle 构建脚本&#xff1a; a、项目级构建脚本 (build.gradle 或 build.gradle.kts)&#xff1a;位于项目的根目录中&#xff0c;用于配置项目范…

Java | Leetcode Java题解之第214题最短回文串

题目&#xff1a; 题解&#xff1a; class Solution {public String shortestPalindrome(String s) {int n s.length();int[] fail new int[n];Arrays.fill(fail, -1);for (int i 1; i < n; i) {int j fail[i - 1];while (j ! -1 && s.charAt(j 1) ! s.charAt…

ASP.NET Core Blazor 5:Blazor表单和数据

本章将描述 Blazor 为处理 HTML 表单提供的特性&#xff0c;包括对数据验证的支持。 1 准备工作 继续使用上一章项目。   创建 Blazor/Forms 文件夹并添加一个名为 EmptyLayout.razor 的 Razor 组件。本章使用这个组件作为主要的布局。 inherits LayoutComponentBase<div …

【Mojo开发新纪元】探索CSS预处理器的集成之路

标题&#xff1a;【Mojo开发新纪元】探索CSS预处理器的集成之路 Mojolicious是一个基于Perl的现代且高性能的Web开发框架&#xff0c;它提供了一套丰富的工具来简化Web开发过程。随着前端技术的发展&#xff0c;CSS预处理器如Sass和Less因其强大的功能和灵活性&#xff0c;已经…

论文 | PRCA: 通过可插拔奖励驱动的上下文适配器拟合用于检索问答的黑盒大语言模型

论文全称&#xff1a;PRCA: Fitting Black-Box Large Language Models for Retrieval Question Answering via Pluggable Reward-Driven Contextual Adapter 核心问题&#xff1a;如何在检索增强式问答&#xff08;ReQA&#xff09;任务中&#xff0c;利用大型语言模型&#xf…

Java面试题:sql优化

表的设计的优化 参考阿里开发手册(嵩山版) 设置合适数值类型(tinyint,int,bigint) 设置合适的字符串类型(char,varchar) 索引优化 SQL语句优化 需要指明字段名称,避免直接使用select*,导致回表查询 避免造成索引失效的写法 尽量用union all代替union,union会多一次过滤…

【C语言入门】初识C语言:掌握编程的基石

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C语言 “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C语言入门 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C语言入门 &#x1f4d2;1. 选择…

Mac OS M3 安装 Docker 并解决芯片不支持问题

有点儿无语&#xff0c;好不容易从Docker官网下载 Apple Chip版本&#xff0c;安装挺快&#xff0c;一试废了。docker --version命令执行挺好&#xff0c;但一下载镜像常用的alpine不能运行。 经查询资料尝试选择了替代品 OrbStack目前感觉挺好用。官网&#xff1a;https://or…

在Linux系统中使用阿里云镜像源安装和配置Docker的详细教程

很多国内小伙伴在Linux上安装Docker经常会遇到网络不可达的问题。那么我们可以使用阿里云镜像来完成Docker的安装&#xff0c;这里是如何在 CentOS 上使用阿里云的 Docker 镜像源的步骤&#xff1a; 1. 删除已有的 Docker 仓库 如果之前添加了任何 Docker 仓库&#xff0c;先…

有哪些AI绘画软件?

以下是一些比较知名的AI绘画软件&#xff1a; 1、DeepArt&#xff1a;基于深度学习技术&#xff0c;可以将照片转换成各种艺术风格的绘画。 2、Artbreeder&#xff1a;通过生成对抗网络&#xff08;GAN&#xff09;&#xff0c;允许用户混合和匹配图像以创建新的艺术作品。 …

单片机关键任务优先级的实现学习

与总体产品联调时&#xff0c;需要各个单机系统严格按照总体要求&#xff0c;进行数据输出&#xff0c;时间的偏差将出现系统异常&#xff0c;控制失败等不稳定情况产生&#xff0c;甚至影响到产品安全。 因此必须确保某些关键任务的优先执行。单片机任务优先级一般有两种方式…

[小试牛刀-习题练]《计算机组成原理》之指令系统

一、选择题 0.【指令-课本习题】某计算机按字节编址&#xff0c;指令字长固定且只有两种指令格式&#xff0c;其中三地址指令29条&#xff0c;二地址指令107条&#xff0c;每个地址字段为6位&#xff0c;则指令字长至少应该是&#xff08;A&#xff09; A.24位 B. 26位 C. 28位…

ctfshow web sql注入 web242--web249

web242 into outfile 的使用 SELECT ... INTO OUTFILE file_name[CHARACTER SET charset_name][export_options]export_options:[{FIELDS | COLUMNS}[TERMINATED BY string]//分隔符[[OPTIONALLY] ENCLOSED BY char][ESCAPED BY char]][LINES[STARTING BY string][TERMINATED…

记一次:poi填充Word模板

前言&#xff1a;笔者在实际工作中需要生成一些报告&#xff0c;但报告的模板是固定的&#xff0c;指定位置需要替换数据或图片&#xff0c;因此总结一下 正题&#xff1a;话不多说&#xff0c;直接贴上工具类吧 package com.lhkj.iot.controller.poi;import java.io.File; i…

Unity丧尸围城Demo总结

1.BasePanel和UIManager 子类面板继承BasePanel&#xff0c;UIManager实现动态创建面板&#xff0c;展示面板&#xff0c;隐藏面板&#xff0c;得到面板 &#xff08;1&#xff09;单例类 &#xff08;2&#xff09;canvas设置为预制体&#xff0c;将新创建的面板设置为该子类 …

【面试题】网络IO多路复用模型之异步事件

目录 异步事件模型的概念 工作流程&#xff1a; WSAEventSelect模型的优势和不足 代码&#xff1a; 异步事件模型的概念 WSAEventSelect模型是WindowsSockets提供的另外一个有用的异步I/O模型。该模型允许一个或多个套接字上接收以事件为基础的网络事件通知。Windows Sock…

面试专区|【40道移动端测试高频题整理(附答案背诵版)】

iOS应用和Android应用测试有什么侧重点&#xff1f; iOS应用和Android应用测试的侧重点略有不同&#xff0c;主要表现在以下几个方面&#xff1a; 分辨率和屏幕尺寸&#xff1a;Android设备的分辨率和屏幕尺寸多种多样&#xff0c;因此&#xff0c;需要测试更多的分辨率和屏幕…

2.Mybatics_映射器与参数

文章目录 映射器与参数一.XML映射器1.创建工具类2.SQL语句操作:3.模糊查询4.返回多个聚合函数的结果5.返回分组后的结果 二.不同个数参数的处理1.单个参数2.对象参数3.多个参数4.传入一个map类型的参数5.添加注册方法引出service层概念 映射器与参数 一.XML映射器 1.创建工具…

Android系统层屏蔽弹出停止运行对话框

项目场景&#xff1a; 车载项目&#xff0c;ATC8257-Android9.0系统平台&#xff0c;福田汽车P3系列项目 项目使用高德公版地图前提是无法获得任何高德定制服务&#xff0c;每次刷完机去切换语言系统会弹出"高德地图已停止运行"弹窗&#xff0c;严重影响用户使用体…

【第三版 系统集成项目管理工程师】第6章 数据工程

持续更新。。。。。。。。。。。。。。。 【第三版】第六章 数据工程 6.1数据采集和预处理6.1.1 数据采集 P2346.1.2 数据预处理6.1.3 数据预处理方法1.缺失数据的预处理-P2352.异常数据的预处理-P2363.不一致数据的预处理-P2364.重复数据的预处理-P2365.格式不符数据的预处理…