基于顺序表的通讯录实现

news2024/9/22 13:31:37

一、前言

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

二、通讯录相关头文件

//Contact.h
#pragma once

#define NAME_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 20
#define GENDER_MAX 20

typedef 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.coloradmin.cn/o/1901638.html

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

相关文章

node的下载、安装、配置和使用(node.js下载安装和配置、npm命令汇总、cnpm的使用)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 愿将腰下剑,直为斩楼兰。 ——《塞下曲》 文章目录 一、node.js的下载、安装和配置1. node.js下…

Latex--制作幻灯片

目录 1.基本介绍 &#xff08;1&#xff09;案例引入 &#xff08;2&#xff09;相关说明 &#xff08;3&#xff09;控制顺序 &#xff08;4&#xff09;帧环境的创建 &#xff08;5&#xff09;内置主题 &#xff08;6&#xff09;生成标题页面 1.基本介绍 &#xff0…

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

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

vue侦听器watch()

侦听器watch&#xff08;&#xff09; 侦听器侦听数据变化&#xff0c;我们可以使用watch 选项在每次响应式属性变化时触发一个函数。 <template><h3>侦听器watch</h3><hr> <p>{{nessage}}</p> <button click"exchage">…

Fill - UVA 10603

网址如下&#xff1a; Fill - UVA 10603 - Virtual Judge (vjudge.net) 感觉有点浮躁&#xff0c;没法完全将思绪投入题的思考中 脑袋糊糊的 一道bfs题 代码如下&#xff1a; #include<queue> #include<cstdio> #include<cstring> #include<vector&g…

计算机网络——数据链路层(以太网扩展、虚拟局域网、高速以太网)

在许多情况下&#xff0c;我们希望把以太网的覆盖范围扩展。本节先讨论在物理层把以太网扩展&#xff0c;然后讨论在数据链路层把以太网扩展。这种扩展的以太网在网络层看来仍然是一个网络。 在物理层扩展以太网 现在&#xff0c;扩展主机和集线器之间的距离的一种简单方法就是…

Apache Seata新特性支持 -- undo_log压缩

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Apache Seata新特性支持 – undo_log压缩 Seata新特性支持 – undo_log压缩 现状 & 痛点…

读书到底有什么意义?从笨小孩到名人的逆袭之路

点击上方△腾阳 关注 作者 l 腾阳 转载请联系授权 读书到底有什么意义&#xff1f; 有一个鸟语花香的农场里&#xff0c;住着老农夫和他的小孙子。 老农夫经常在清晨会坐在窗边&#xff0c;捧着厚厚的《圣经》&#xff0c;沉浸在知识的海洋里。 小孙子问他&#xff1a;…

政策公告与提醒

自 2024 年 4 月 3 日起,您将至少有 30 天的时间来更新应用,使其符合下方所述的政策变更。 我们将推出“儿童安全标准”政策,规定社交应用和约会交友应用必须遵循特定标准,并在 Play 管理中心内以自行认证的形式证明合规后才能发布。 为了提高健康相关应用在 Google Play…

BulingBuling - 作息安排 [Reset Your Routine] - 1

The Blinkist Team: [ Reset Your Routine ] 如果你发现自己很难按部就班&#xff0c;或者陷入工作效率低的困境&#xff0c;那么你可能需要重新调整一下作息时间&#xff01;从睡眠和营养&#xff0c;到待办事项和井井有条--本指南为你提供了各种技巧和策略&#xff0c;让你的…

linux下高级IO模型

高级IO 1.高级IO模型基本概念1.1 阻塞IO1.2 非阻塞IO1.3 信号驱动IO1.4 IO多路转接1.5 异步IO 2. 模型代码实现2.1 非阻塞IO2.2 多路转接-selectselect函数介绍什么才叫就绪呢&#xff1f;demoselect特点 2.3 多路转接-pollpoll函数介绍poll优缺点demo 2.4 多路转接-epoll&…

Python通过HiperMATRIX API写数据

PyCharm编程和调试 参考&#xff1a;写入数据接口 | HiperM 产品帮助中心 其中token 我偷懒了&#xff0c;只是调试&#xff0c;打开HiperMATRIX界面&#xff0c;登录&#xff0c;从浏览器console里面找到token value。 URL中有设备的ID&#xff0c;比如7123766549772505088&…

Linux期末考试复习资料分享(可打印)

Linux期末考试复习资料分享&#xff08;可打印&#xff09; 祝大家都有个好成绩&#xff5e; 获取链接:https://pan.baidu.com/s/1TrAqkeGTv6pYVHqxJIsyDw 提取码&#xff1a;x0za 获取链接:https://pan.baidu.com/s/1TrAqkeGTv6pYVHqxJIsyDw 提取码&#xff1a;x0za

Zynq7000系列FPGA中DMA引擎编程指南

DMA引擎的编程指南通常涉及一系列步骤和API调用&#xff0c;以确保数据在内存之间的高效传输&#xff0c;而无需CPU的直接干预。 DMA引擎的编程指南包括以下部分&#xff1a; 一、编写微代码为AXI事务编写CCRx程序 通道微码用于设置dmac.CCRx寄存器以定义AXI事务的属性。这是…

Vue中Class数据绑定

Class数据绑定 数据绑定的一个常见需求场景是操作CSS class列表&#xff0c;因为class是attribute&#xff08;属性&#xff09;&#xff0c;我们可以和其他attribute一样使用v-bind 将它们和动态的字符串绑定。但是&#xff0c;在处理比较复杂的绑定时&#xff0c;通过拼接生…

银行信用卡风险大数据分析与挖掘2024

银行信用卡风险大数据分析与挖掘 使用excel数据挖掘功能完成 一、信用卡客户信用等级影响因素分析与挖掘 基于客户信用记录表 1. 数据预处理 浏览数据 客户等级占比&#xff0c;其中优质客户占比较少&#xff0c;风险客户很多&#xff0c;分析影响客户信用等级的原因 年…

linux下的网络编程

网络编程 1. 网络基础编程知识1.1网络字节序问题1.2 常用socket编程接口1.2.1 sockaddr1.2.2 ip地址转换函数1.2.4 socket()1.2.3 bind()1.2.4 listen()1.2.5 accept()1.2.6 connect() 1.3 以udp为基础的客户端连接服务器的demo1.4 以udp为基础的的服务器聊天室功能demo1.5 基于…

解决 MEX 文件 ‘xxx.mexw64‘ 无效: 找不到指定的模块。的问题

1.问题描述 在matlab R2021b中运行编译好后的gptoolbox工具箱中的函数[SVtemp,SFtemp,IF] selfintersect(V,F);报错如下 MEX 文件 E:\MATLAB_File\gptoolbox\mex\selfintersect.mexw64 无效: 找不到指定的模块。出错 offset_bunny (第 15 行) [SVtemp,SFtemp,IF] selfinter…

【pyqt-实训训练】串口助手

串口助手 前言一、ui设计二、ui的控件命名三、ui转py使用类的方法【扩展】使用ui文件导入&#xff01;P7的小错误解决办法 总结 前言 我的惯例就是万物之始&#xff0c;拜见吾师&#x1f970;⇨pyqt串口合集 最开始的时候我想的是&#xff0c;学了那么久的pyqt&#xff0c;我…

加入新数据预测,基于黏菌优化算法SMA优化SVM支持向量机回归预测(多输入单输出)

加入新数据预测&#xff0c;基于黏菌优化算法SMA优化SVM支持向量机回归预测&#xff08;多输入单输出&#xff09; 1.数据均为Excel数据&#xff0c;直接替换数据就可以运行程序。 2.所有程序都经过验证&#xff0c;保证程序可以运行。 3.具有良好的编程习惯&#xff0c;程序…