基于顺序表的通讯录实现

一、前言

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

二、通讯录相关头文件

//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.xdnf.cn/news/1473843.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Hugging face Transformers(2)—— Pipeline

Hugging Face 是一家在 NLP 和 AI 领域具有重要影响力的科技公司&#xff0c;他们的开源工具和社区建设为NLP研究和开发提供了强大的支持。它们拥有当前最活跃、最受关注、影响力最大的 NLP 社区&#xff0c;最新最强的 NLP 模型大多在这里发布和开源。该社区也提供了丰富的教程…

C++友元函数和友元类的使用

1.友元介绍 在C++中,友元(friend)是一种机制,允许某个类或函数访问其他类的私有成员。通过友元,可以授予其他类或函数对该类的私有成员的访问权限。友元关系在一些特定的情况下很有用,例如在类之间共享数据或实现特定的功能。 友元可以分为两种类型:类友元和函数友元。…

高级计算机体系结构--期末教材复习

Chap2 性能评测和并行编程性能评测并行编程为什么需要三次 barrier改进方法 Chap3 互连网络交换和路由二维网格中 XY 路由 死锁、活锁及饿死死锁避免的方法&#xff1a;虚通道、转弯模型二维网格中最小 西向优先、北向最后和负向优先算法转弯模型&#xff1a;超立方体的部分自适…

前端面试题19(vue性能优化)

Vue.js应用的性能优化是一个多方面的过程&#xff0c;涉及初始化加载、运行时渲染以及用户交互等多个环节。以下是一些关键的Vue性能优化策略&#xff0c;包括详细的说明和示例代码&#xff1a; 1. 懒加载组件 对于大型应用&#xff0c;可以使用懒加载来减少初始加载时间。Vu…

JavaWeb----JSPJSTL

目录 JSP显隐注释在JSP中写java程序JSP的指令标签JSP中的四大域对象简易版用户登录EL表达式 JSTL条件动作标签if标签 choose\when\otherwise标签迭代标签格式化动作标签 用户登录实例查看是否安装了mysql用户登录界面后台实现 JSP JSP全名是Java Server Pages&#xff0c;它是建…

电机控制杂谈——增量式的预测电流控制的优势在哪?

1.前言 前几天看到这么个问题。“模型预测控制如何消除静态误差” 评论说用增量式的预测控制。 这个回答让我想起来我大四下看的这篇论文。现在都一百多被引用了。 但是苦于当时能力有限&#xff0c;没办法复现这个文章。 所以现在想重新验证一下。 2.静态误差和电机磁链有…

[CP_AUTOSAR]_分层软件架构_内容详解

目录 1、软件分层内容1.1、Microcontroller Abstraction Layer1.2、ECU Abstraction Layer1.2.1、I/O HW Abstraction1.2.2、Communication Hardware Abstraction1.2.3、Memory Hardware Abstraction1.2.4、Onboard Device Abstraction1.2.5、Crypto Hardware Abstraction 1.3、…

Apache Seata分布式事务启用Nacos做配置中心

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Seata分布式事务启用Nacos做配置中心 Seata分布式事务启用Nacos做配置中心 项目地址 本文作…

便携式气象站:探索自然的智慧伙伴

在探索自然奥秘、追求科学真理的道路上&#xff0c;气象数据始终是我们不可或缺的指引。然而&#xff0c;传统的气象站往往庞大而笨重&#xff0c;难以在偏远地区或移动环境中灵活部署。 便携式气象站&#xff0c;顾名思义&#xff0c;是一种小巧轻便、易于携带和安装的气象观测…

VitePress美化

参考资料&#xff1a; https://blog.csdn.net/weixin_44803753/article/details/130903396 https://blog.csdn.net/qq_30678861/category_12467776.html 站点信息修改 首页部分的修改基本都在.vitepress/config.mts,这个文件内修改。 title 站点名称 description 描述 top…

Vben:表格的表头和表格的内容对不齐,以及解决方法

文章目录 一、问题描述二、解决方法 一、问题描述 基于Vue-Vbne-admin框架进行前端开发的时候&#xff0c;调用表格useTable函数实现表格之后&#xff0c;发现表格的表头和表格的内容对不齐。如下图所示。针对这种情况&#xff0c;本文记录了解决方法。 调用的模块如下&#x…

【力扣 - 每日一题】3099. 哈沙德数 | 模拟 (Go/C++)

题目内容 如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&#xff09;。给你一个整数 x 。如果 x 是 哈沙德数 &#xff0c;则返回 x 各个数位上的数字之和&#xff0c;否则&#xff0c;返回 -1 。 示例 1&#xff1…

使用 ESP32-WROOM + DHT11 做个无屏温湿度计

最近梅雨天&#xff0c;有个房间湿度很大&#xff0c;而我需要远程查看温湿度&#xff0c;所以无所谓有没有显示屏&#xff0c;某宝上的温湿度计都是带屏的&#xff0c;如果连WIFI查看温湿度操作也比较麻烦&#xff0c;还需要换电池&#xff0c;实在不能满足我的需求&#xff0…

SpringBoot新手快速入门系列教程四:创建第一个SringBoot的API

首先我们用IDEA新建一个项目&#xff0c;请将这些关键位置按照我的设置设置一下 接下来我将要带着你一步一步创建一个Get请求和Post请求&#xff0c;通过客户端请求的参数&#xff0c;以json格式返回该参数{“message”:"Hello"} 1,先在IDE左上角把这里改为文件模式…

笔记:SpringBoot+Vue全栈开发

笔记&#xff1a;SpringBootVue全栈开发 1. 开发环境热部署2. SpringBoot RestController的使用3. SpringBoot实现文件上传4. 配置拦截器5. Restful服务Swagger6. 使用MyBatis-Plus进行数据库操作7. 多表查询、条件查询及分页查询 1. 开发环境热部署 使用spring-boot-devtools…

泛微开发修炼之旅--31海康威视综合安防管理系统组织机构同步代码方案及源码

31海康威视综合安防管理系统组织机构同步代码方案及源码 一、使用场景 我们在一个项目中有一个和海康威视综合安防管理系统进行组织机构同步接口&#xff0c;接下来我们看下实现的源码 31海康威视综合安防管理系统组织机构同步代码方案及源码

【qt】如何获取本机的IP地址?

需要用到这个类QHostInfo和pro里面添加network模块 用这个类的静态函数forName()来获取该主机名的信息 返回的就是这个类 这个QHostInfo类就包括主机的IP地址信息 用静态函数addresses()来获取 返回的是一个QHostAddress的容器 QList<QHostAddress>addrList hostIn…

【车载开发系列】GIT安装详细教程

【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程一. GIT软件概念二. GIT安装步骤三. GIT安装确认三. GIT功能使用1&#xff09;Git Bash2&#xff09;Git CMD3&#xff09;Git FAQs4&#xff09;Git GUI 一. GIT软件概念 G…

[CTF]-PWN:House of Banana堆块题型综合分析

搭配largebin attack&#xff1a; 例题&#xff08;ISCC2024 heapheap)&#xff1a; 版本&#xff1a;glibc2.31 知识点&#xff1a;largebin attack、house of banana、uaf 查看保护 查看ida delete存在uaf漏洞 largebin attack手法&#xff1a; #创建4个堆块&#xff0…

Django学习第六天

启动项目命令 python manage.py runserver 取消模态框功能 js实现列表数据删除 第二种实现思路 使用jquery修改模态框标题 编辑页面拿到数据库数据显示默认数据功能实现 想要去数据库中获取数据时&#xff1a;对象/字典 三种不同的数据类型 使用Ajax传入数据实现表单编辑&…