顺序表实现——通讯录

news2024/7/7 14:51:51

前言:

        通过对数据结构--顺序表的学习,了解了顺序表的增加数据,删除数据等功能;我们就可以基于顺序表来实现通讯录,接下来就一起来实现通讯录。

首先我们需要存储通讯录中联系人信息,这里创建一个结构体,

存储联系人姓名、性别、年龄、电话、住址等信息

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

typedef struct personinfo //联系人信息
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age; //年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//住址
}person;

这里使用#define定义常量,以后方便修改

现在创建好了应该结构体(联系人信息)那又如何有顺序表来实现呢?

        在数据结构--顺序表中,实现顺序表时,存储的是整形数据,那现在需要将用户信息存储起来,我们就让顺序表存储的数据是我们结构体(联系人信息)。

这里只需将数据类型中 int 改为 结构体类型即可;

typedef struct personinfo Type;//person

因为在结构体定义时就重命名为了person,这里可以使用person替换struct personinfo

        当然,为了方便操作,我们也会将(动态)顺序表(SeqList)重命名成通讯录(Contact)

不过这里需要注意的时:我们是基于顺序表来实现通讯录,我们需要通讯录的头文件,也需要用到顺序表的相关代码,两个头文件在使用时都会用到另一个头文件的东西,而头文件又不能相互包含,(这里在通讯录头文件Contact.h中只需声明顺序表结构体就可以了(不可以直接使用重命名后的结构体名)),顺序表实现的头文件直接包含Contact.h即可(因为会涉及到数据类型重命名和插入、查找数据等)。

        到这里,对于通讯录的实现准备工作已经做的差不多了,接下来就来就实现通讯录:

通讯录功能预览:

我们想要通讯录实现以下几种功能:

  1. 能够保存联系人信息姓名、性别、年龄、电话、地址等
  2. 增加联系人信息
  3. 删除指定联系人
  4. 查找指定联系人
  5. 修改指定联系人
  6. 显示联系人信息

先来看以下这些功能实现代码的头文件

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 50

typedef struct personinfo //联系人信息
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age; //年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//住址
}person;

typedef struct SeqList Con;//重命名顺序表

//通讯录初始化
void ConInit(Con* con);
//通讯录销毁
void ConDesTroy(Con* con);
//查看通讯录
void ConShow(Con* con);
//添加联系人
void ConAdd(Con* con);
//修改联系人
void Conrev(Con* con);
//删除联系人
void ConDel(Con* con);
//查找联系人
void ConFind(Con* con);

接下来就一一实现这些功能函数

通讯录初始化

通讯录销毁

        通讯录的初始化和销毁其实就是顺序表的初始化和销毁,这里直接使用顺序表的初始化和销毁函数即可。

//通讯录初始化
void ConInit(Con* con)
{
	SLInit(con);
}
//通讯录销毁
void ConDesTroy(Con* con)
{
	SLDesTroy(con);
}

查看通讯录

        这里查看联系人信息也就是将联系人信息输出(打印)到电脑屏幕上,先看以下预期效果图

这样在下面依次输出即可,这里就需要一些格式

//查看通讯录
void ConShow(Con* con)
{
	printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%-10s%-10s%-10d%-10s%-10s\n", 
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}

        我这里使用%-10s(%-10d)来限制输出对齐的格式%-10d是靠左对齐。(这里也可以给更多%-20d等)

添加联系人

        接下来就是添加联系人信息,这个这里就先从键盘上读取数据存储进来

}
//添加联系人
void ConAdd(Con* con)
{
	person psi;
	printf("请输入添加的联系人姓名:\n");
	scanf("%s", psi.name);
	printf("请输入添加的联系人性别:\n");
	scanf("%s", psi.gender);
	printf("请输入添加的联系人年龄:\n");
	scanf("%d", &psi.age);
	printf("请输入添加的联系人电话:\n");
	scanf("%s", psi.tel);
	printf("请输入添加的联系人住址:\n");
	scanf("%s", psi.addr);

	SLAddEnd(con, psi);
	printf("添加成功\n");
}

这里也可以像下面这种方式直接输入到顺序表数据中。

//添加联系人
void ConAdd(Con* con)
{
	if (con->size >= con->num) {
		Conzengrong(con);
	}
	printf("请输入添加联系人的姓名:\n");
	scanf("%s", con->arr[con->size].name);
	printf("请输入添加联系人的性别:\n");
	scanf("%s", con->arr[con->size].gender);
	printf("请输入添加联系人的年龄:\n");
	scanf("%d", &con->arr[con->size].age);
	printf("请输入添加联系人的电话:\n");
	scanf("%s", con->arr[con->size].tel);
	printf("请输入添加联系人的地址:\n");
	scanf("%s", con->arr[con->size].addr);
	printf("添加成功\n");
	con->size++;
}

        但我们这是基于顺序表来实现的通讯录,这里就使用第一种方式。

这里就不一一测试了;

删除联系人

        删除联系人,我们首先要找到这个联系人信息,就要先写一个函数先找到联系人信息(在查找联系人,修改联系人都会用到):

//按照名字查找
int Find_name(Con* con, char* name)
{
	for (int i = 0; i < con->size; i++) 
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

这里如果找到联系人数据,就返回其下标,如果找不到就返回-1;

        接下来就通过查找函数的返回值来删除数据:这里会用到顺序表中删除指定位置的函数

//删除联系人
void ConDel(Con* con)
{
	char name[NAME_MAX];
	printf("请输入删除的联系人姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		printf("需要删除的联系人不存在\n");
		return;
	}
	SLDeleve(con, find);
	printf("删除成功\n");
}

当然这里也可以不使用顺序表的函数,直接进行查找到下标如何进行删除,这里就不添加这种方式的代码了,(其实就是将顺序表的代码写到这个函数中)

查找联系人

        与删除函数相同的是,查找也需要先找到指定联系人的下标,再通过下标将数据输出出来

代码如下:

//查找联系人
void ConFind(Con* con)
{
	char name[NAME_MAX];
	printf("请输入查找的联系人姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		printf("查找的联系人不存在\n");
		return;
	}
	printf("查找成功\n");
	printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
	printf("%-10s%-10s%-10d%-10s%-10s\n",
		con->arr[find].name,
		con->arr[find].gender,
		con->arr[find].age,
		con->arr[find].tel,
		con->arr[find].addr);
}

修改联系人

        修改与删除和查找都需要先找到指定联系人数据的下标,再通过下标对联系人信息进行操作

//修改联系人
void Conrev(Con* con)
{
	char name[NAME_MAX];
	printf("请输入需要修改的联系人姓名:\n");
	scanf("%s", name);
	int find = Find_name(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");
}

到这里通讯录的基本代码已经完了,先来写测试代码来测试以下

测试代码test.c:

#include"SeqList.h"

void Contact()
{
	int n = 0;
	Con con;
	ConInit(&con);
	do
	{
		printf("******************************通讯录******************************\n");
		printf("********************1.添加联系人  2.删除联系人********************\n");
		printf("********************3.修改联系人  4.查找联系人********************\n");
		printf("********************5.查看通讯录  0.退出通讯录********************\n");
		printf("******************************************************************\n");
		printf("------------------------------请选择------------------------------\n");
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			ConAdd(&con);
			break;
		case 2:
			ConDel(&con);
			break;
		case 3:
			Conrev(&con);
			break;
		case 4:
			ConFind(&con);
			break;
		case 5:
			ConShow(&con);
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入\n");

		}
	} while (n);
	ConDesTroy(&con);
}
int main()
{
	Contact();
	return 0;
}

结果预览

顺序表实现通讯录

        当然这样写,我们的通讯录信息再程序结束后就丢失了,要想长久保存,我们就要将通讯录信息写到文件中,文件操作相关知识在之前有所了解

这里就不进行文件相关操作了,可以自行尝试

代码总览

        有很多是顺序表实现的相关代码,这里可以直接拿来用,这里只展示通讯录的相关代码,顺序表的代码可以查看上篇文章 顺序表

Contact.c

#include"SeqList.h"
#include"Contact.h"

//通讯录初始化
void ConInit(Con* con)
{
	SLInit(con);
}
//通讯录销毁
void ConDesTroy(Con* con)
{
	SLDesTroy(con);
}
//查看通讯录
void ConShow(Con* con)
{
	printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%-10s%-10s%-10d%-10s%-10s\n", 
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}
//添加联系人
void ConAdd(Con* con)
{
	person psi;
	printf("请输入添加的联系人姓名:\n");
	scanf("%s", psi.name);
	printf("请输入添加的联系人性别:\n");
	scanf("%s", psi.gender);
	printf("请输入添加的联系人年龄:\n");
	scanf("%d", &psi.age);
	printf("请输入添加的联系人电话:\n");
	scanf("%s", psi.tel);
	printf("请输入添加的联系人住址:\n");
	scanf("%s", psi.addr);

	SLAddEnd(con, psi);
	printf("添加成功\n");
}
//按照名字查找
int Find_name(Con* con, char* name)
{
	for (int i = 0; i < con->size; i++) 
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void ConDel(Con* con)
{
	char name[NAME_MAX];
	printf("请输入删除的联系人姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		printf("需要删除的联系人不存在\n");
		return;
	}
	SLDeleve(con, find);
	printf("删除成功\n");
}
//修改联系人
void Conrev(Con* con)
{
	char name[NAME_MAX];
	printf("请输入需要修改的联系人姓名:\n");
	scanf("%s", name);
	int find = Find_name(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 ConFind(Con* con)
{
	char name[NAME_MAX];
	printf("请输入查找的联系人姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		printf("查找的联系人不存在\n");
		return;
	}
	printf("查找成功\n");
	printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
	printf("%-10s%-10s%-10d%-10s%-10s\n",
		con->arr[find].name,
		con->arr[find].gender,
		con->arr[find].age,
		con->arr[find].tel,
		con->arr[find].addr);
}

Coontact.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 50

typedef struct personinfo //联系人信息
{
	char name[NAME_MAX];//姓名
	char gender[GENDER_MAX];//性别
	int age; //年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//住址
}person;

typedef struct SeqList Con;//重命名顺序表

//通讯录初始化
void ConInit(Con* con);
//通讯录销毁
void ConDesTroy(Con* con);
//查看通讯录
void ConShow(Con* con);
//添加联系人
void ConAdd(Con* con);
//修改联系人
void Conrev(Con* con);
//删除联系人
void ConDel(Con* con);
//查找联系人
void ConFind(Con* con);

感谢各位大佬支持并指出问题,

如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

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

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

相关文章

Vue报错:Module not found: Error: Can‘t resolve ‘less-loader‘ in ‘文件地址‘

原因&#xff1a;Webpack无法找到 less-loader 模块&#xff0c;但在<style langless></style>中进行使用。less-loader 是一个Webpack的加载器&#xff0c;它用于将less文件编译成CSS。如果Webpack无法解析这个加载器&#xff0c;它就无法处理less文件&#xff0c…

【C语言内存函数】

目录 1.memcpy 使用 模拟实现 2.memmove 使用 模拟实现 3.memset 使用 4.memcmp 使用 1.memcpy 使用 void * memcpy ( void * destination, const void * source, size_t num );目的地址 源地址 字节数 destination&#xff1a;指向要复制内…

EDA 虚拟机 Synopsys Sentaurus TCAD 2017.09 下载

下载地址&#xff08;制作不易&#xff0c;下载使用需付费&#xff0c;不能接受的请勿下载&#xff09;&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1327I58gvV1usWSqSrG7KXw?pwdo03i 提取码&#xff1a;o03i

heic图片怎么转成jpg格式,这6个方法亲测有用(超简单)

heic图片怎么转成jpg&#xff1f;现在我们都喜欢用手机来拍摄记录生活中的美好瞬间&#xff0c;照片太多的话我们为了不占用手机内存&#xff0c;会把照片导入电脑进行储存。但是苹果手机用户在导入相册照片时可能会遇到以下问题&#xff1a;因为苹果手机拍摄照片格式默认为hei…

友思特应用 | 多接口的智驾无忧:GigE相机在自动驾驶数据采集系统的稳定应用

导读 GigE接口相机为自动驾驶数据采集提供了高性价比的选择。在此基础上&#xff0c;友思特搭建了多GigE接口支持PTP的采集设备系统级方案 BRICK2&#xff0c;为多传感器数据记录测试提供了完整的解决方案。 GigE接口相机与智能驾驶数据采集 智能驾驶技术的发展已经成为当今科…

【前端vue3】TypeScrip-元组类型和枚举类型

元组类型 元组就是数组的变形 元组&#xff08;Tuple&#xff09;是固定数量的不同类型的元素的组合。 元组与集合的不同之处在于&#xff0c;元组中的元素类型可以是不同的&#xff0c;而且数量固定。元组的好处在于可以把多个元素作为一个单元传递。如果一个方法需要返回多个…

day03-主页模块-修改密码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.获取用户资料在Vuex中共享登录成功跳转到主页之后&#xff0c;可以获取用户资料&#xff0c;获取的资料在Vuex中共享&#xff0c;这样用户就可以很方便的获取该信…

【基础算法总结】分治—快排

分治—快排 1.分治2.颜色分类3.排序数组4.数组中的第K个最大元素5.库存管理 III 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.分治 分治…

Node.js安装及配置

文章目录 1.安装Node.js2.创建目录3.配置环境变量4.配置全局安装路径和缓存路径(可选)配置Webstorm 1.安装Node.js https://registry.npmmirror.com/binary.html?pathnode 推荐安装18.x版本 2.创建目录 下载解压后进入目录&#xff0c;创建node_global和node_cache两个空文…

在嵌入式商用里面哪款RTOS(实时操作系统)比较多人用?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 传统的RTOS和嵌入式Linu…

【氮化硼】 h-BN薄膜的控制辐射损伤和边缘结构

摘要: 本文展示了通过化学剥离法合成的六方氮化硼(h-BN)膜在80 kV电子束辐照下表现出比石墨烯更高的抗辐射损伤能力。研究表明,即使在长时间电子束辐照下,单层h-BN也不会形成空位缺陷或发生非晶化。实验观察到在h-BN薄膜中,锯齿形边缘结构占主导地位,且这些边缘主要由氮…

6个操作简单又好用的实用办公工具

分享6个操作简单又好用的实用办公工具&#xff0c;手机和电脑上的都有&#xff0c;好好使用可以让工作效率翻倍&#xff01; 1.方方格子 一个大型的的【Excel工具箱】&#xff0c;支持32位和64位Office&#xff0c;可直接作为插件使用&#xff0c;功能覆盖非常全面&#xff0c…

MySQL实战-4 | 深入浅出索引(上)(下)

什么是数据库索引&#xff0c;索引又是如何工作的呢&#xff1f; 一句话简单来说&#xff0c;索引的出现其实就是为了提高数据查询的效率&#xff0c;就像书的目录一样。一本 500 页的书&#xff0c;如果你想快速找到其中的某一个知识点&#xff0c;在不借助目录的情况下&…

MySQL:设计数据库与操作

设计数据库 1. 数据建模1.1 概念模型1.2 逻辑模型1.3 实体模型主键外键外键约束 2. 标准化2.1 第一范式2.2 链接表2.3 第二范式2.4 第三范式 3. 数据库模型修改3.1 模型的正向工程3.2 同步数据库模型3.3 模型的逆向工程3.4 实际应用建议 4. 数据库实体模型4.1 创建和删除数据库…

学习笔记(linux高级编程)10

IPC 进程间通信 interprocess communicate 三大类&#xff1a; 1、古老的通信方式 无名管道 有名管道 信号 2、IPC对象通信 system v BSD suse fedora kernel.org 消息队列(用的相对少&#xff0c;这里不讨论) 共享内存 信号量集 3、socket通信 网络通信 特…

【MySQL】mysql访问

mysql访问 1.引入MySQL 客户端库2.C/C 进行增删改3.查询的处理细节4.图形化界面访问数据库4.1下载MYSQL Workbench4.2MYSQL Workbench远程连接数据库 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&a…

基于CNN的股票预测方法【卷积神经网络】

基于机器学习方法的股票预测系列文章目录 一、基于强化学习DQN的股票预测【股票交易】 二、基于CNN的股票预测方法【卷积神经网络】 文章目录 基于机器学习方法的股票预测系列文章目录一、CNN建模原理二、模型搭建三、模型参数的选择&#xff08;1&#xff09;探究window_size…

8619 公约公倍

这个问题可以通过计算最大公约数 (GCD) 和最小公倍数 (LCM) 来解决。我们需要找到一个整数&#xff0c;它是 a, b, c 的 GCD 的倍数&#xff0c;同时也是 d, e, f 的 LCM 的约数。 以下是解决这个问题的步骤&#xff1a; 1. 计算 a, b, c 的最大公约数。 2. 计算 d, e, f 的最…

SAP MM模块的ATP检查

前面几篇文章都演示和说明ATP的一些设置和操作&#xff0c;通常情况下ATP的检查PP模块&#xff0c;SD模块用的相对来说是比较多的&#xff0c;但是实际上MM模块也会遵循ATP的可用性的检查规则。 当我们在做311、301等移动类型时&#xff0c;系统会根据相应的可用性检查规则&am…

大模型应用开发实战基础

大模型应用开发实战基础 1. 背景 大模型如日中天&#xff0c;各行各业都受它影响&#xff0c;但是作为程序员&#xff0c;除了让它翻译代码不知道用它干什么&#xff0c;就像是拿着锤子的木匠&#xff0c;找不到钉子在哪。一边听着别人说2024是AI元年&#xff0c;一边又不知所…