通讯录项目—顺序表实现

news2025/2/25 0:54:48

     在上次我介绍顺序表后相信大家对顺序表有了一定的了解,现在就让我们来练练如何用它,这篇是在顺序表基础上新增的(建议看看线性表—顺序表实现-CSDN博客)。

目录

通讯录简介

创建用户信息

适配和理解通讯录

功能实现

初始化通讯录

销毁通讯录

增加用户信息

删除指定用户信息

查找用户信息

修改用户信息

显示用户信息

全代码

Contact.h

Contact.c


通讯录简介

     下面是通讯录要实现的功能。

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

创建用户信息

     在创建用户信息前依然是要创建两个项目Contact.h,Contact.c用来存放新增的代码。

     用户信息里包含名字,性别,年龄,电话,地址等这需要用结构体来定义。我把结构体给重命名为penInfo。数组的大小我把它定义为了常量(方便后期更改)。

#define NAME_MAX 20
#define GEMDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

typedef struct personInfo
{
	char name[NAME_MAX];//名字
	char gender[GEMDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//地址
}peoInfo;

typedef struct SeqList Contact;

     大家可能注意到了这段代码的最后一行有这么一段话typedef struct SeqList Contact,有什么用呢?

     我会在下面的适配和理解通讯录中详解。

适配和理解通讯录

     之前顺序表的arr是指向int类型的指针,但现在它需要指向结构体。还记得为什么要创造SLDataType吗?它是用来表示arr的类型。所以只要把int换成penInfo就可以了  (这里要把Contact.h放在SeqList.h里否则penInfo是未定义的)。

//SeqList.c文件中
typedef peoInfo SLDataType;

     现在让我们回到 typedef struct SeqList Contact 这段代码中。

     再说之前要知道对通讯录操作其实就是对顺序表操作,即通讯录就是顺序表,这其实就是把顺序表的名字改为通讯录。

     这里其实不写这段代码也是OK的。但是,你是要对通讯录操作。如果不改名字,那就是对顺序表操作(虽然它们一样)。你想啊,通讯录写的好好的突然出现顺序表,在我们看来还好但是对于其他人来说就很懵。这里改名字其实就是为了更方便理解

     既然想用顺序表那要在Contact.h里包含SeqList.h头文件,但是头文件是不能相互包含的。所以这里要对顺序表的结构体进行前置声明。这里不能用SL,因为是先定义完顺序表结构体之后在重命名的,如果直接用SL会被认为是未定义的。所以要用 struct SeqList 。

//这种是错误的!!!
struct SeqList;//前置声明
typedef SL Contact;

     

     这是正确的!!!

struct SeqList;//前置声明
typedef struct SeqList Contact;

     可以把前置声明放在重命名里,最后就变成了这样。

typedef struct SeqList Contact;

     用户信息的结构体就是放在通讯录的每一个下标里。

     只要把这里给理解了,下面的代码就很轻松了。 

功能实现

初始化通讯录

     初始化调用一下SLInit函数就好。

//初始化
void ContactInit(Contact* con)
{
	SLInit(con);
}

销毁通讯录

     销毁调用一下SLDestroy函数就好。

//销毁
void ContactDesTroy(Contact* con)
{
	SLDestroy(con);
}

增加用户信息

     这里创建一个penInfo的变量info。然后一个一个输入内容。最后调用SLpushBack尾插即可。

//增加
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);
    printf("增加成功!\n");
}

     大家可能注意到了只有年龄的scanf中加了&,为什么呢?

     因为它不是数组,其它都是数组。

删除指定用户信息

     在删除数据前要先检查有无该人,其实不光是删除还有查找,修改的函数都要用到。所以把它独立成一个函数,函数名是Findbyname。

     我在这里是用名字来查找的,遍历一遍如果存在返回顺序表下标,否则返回-1。

     判断是否存在的判断条件,我是用strcmp函数来实现的,如果它的返回值为0则存在。

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;
}

     剩下的要先创建一个数组来存放要删除人的名字,然后调用Findbyname函数,如果返回值小于0则退出。否则调用SLErase函数用来删除。

//删除
void ContactDel(Contact* con)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除联系人的名字;\n");
	scanf("%s", name);
	int find = Findbyname(con, name);
	if (find < 0)
	{
		printf("该人不存在\n");
		return;
	}
	SLErase(con, find);
	printf("删除成功!\n");
}

     注意:开辟数组的大小要和结构体(penInfo)的名字数组大小一样大。

查找用户信息

     依然是要开辟数组然后调用Findbyname函数,如果小于0则退出,否则打印此人的信息。

//查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人的名字;\n");
	scanf("%s", name);
	int find = Findbyname(con, name);
	if (find < 0)
	{
		printf("该人不存在\n");
		return;
	}
	printf("名字  性别  年龄  电话  地址\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);
}

修改用户信息

     前面的代码同上,只不过如果返回值大于0则重新输入他的信息即可。

//修改
void ContactModify(Contact* con)
{
	char name[NAME_MAX] = { 0 };
	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 ContactShow(Contact* con)
{
	for (int i = 0; i < con->size; i++)
	{
		printf("名字  性别  年龄  电话  地址\n");
		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);
	}
}

全代码

Contact.h

#define NAME_MAX 20
#define GEMDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

typedef struct personInfo
{
	char name[NAME_MAX];//名字
	char gender[GEMDER_MAX];//性别
	int age;//年龄
	char tel[TEL_MAX];//电话
	char addr[ADDR_MAX];//地址
}peoInfo;

typedef struct SeqList Contact;

//初始化
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 "SeqList.h"
#include "Contact.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);
	printf("增加成功!\n");
}


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] = { 0 };
	printf("请输入要删除联系人的名字;\n");
	scanf("%s", name);
	int find = Findbyname(con, name);
	if (find < 0)
	{
		printf("该人不存在\n");
		return;
	}
	SLErase(con, find);
	printf("删除成功!\n");
}

//修改
void ContactModify(Contact* con)
{
	char name[NAME_MAX] = { 0 };
	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] = { 0 };
	printf("请输入要查找联系人的名字;\n");
	scanf("%s", name);
	int find = Findbyname(con, name);
	if (find < 0)
	{
		printf("该人不存在\n");
		return;
	}
	printf("名字  性别  年龄  电话  地址\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);
}

//展示
void ContactShow(Contact* con)
{
	for (int i = 0; i < con->size; i++)
	{
		printf("名字  性别  年龄  电话  地址\n");
		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);
	}
}

     好了讲到这儿就差不多讲完了,希望你能有所收获。如果有错误的地方请及时指出,有什么不懂的地方可以私信我哈。

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

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

相关文章

【高阶数据结构】图--邻接矩阵、邻接表、BFS、DFS、Kruskal、Prime

图--邻接矩阵、邻接表、BFS、DFS、Kruskal、Prime 一、图的概述1、概述&#xff08;纯理论部分&#xff09;2、邻接矩阵&#xff08;实现一个添加边的图&#xff09;&#xff08;1&#xff09;思路介绍&#xff08;2&#xff09;代码部分&#xff08;3&#xff09;测试部分 3、…

系统如何做好安全加固?

一、Windows系统 Windows系统出厂时&#xff0c;微软为了兼容性&#xff0c;默认并未对系统安全做严格的限制&#xff0c;因此还需要做一些基本的安全加固&#xff0c;方可防止黑客入侵。 1、系统补丁更新 为什么要更新系统补丁&#xff1f;很多人感觉漏洞更新没必要&#x…

基准电流源仿真

注意连线PMOS必须连接到VDD上&#xff0c;NMOS练到GND上 1.记得选择PNP之后&#xff0c;直接按Q就可以直接选择并联个数&#xff0c;不需要用器件。 2.记得调整放大器如图所示&#xff0c;否则会出错。 3.记得先调整PMOS的宽长比 4.按比例调节R2和R3的阻值 5.仿真的时候&#…

nlp课设 - 基于BERT 的情感分类

基于BERT 的情感分类 主要论文&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff08;双向Transformer 的预训练&#xff09; 核心技术&#xff1a; Embedding 、Attention --> Transformer 任务简介、拟解决问题…

springboot+vue+mybatis图书推荐管理系统的设计与实现+PPT+论文+讲解+售后

随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;图书推荐管理系统展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为解决…

医学论文摘要翻译 中译英哪里比较专业

论文摘要是对论文内容不加注释和评论的简短陈述&#xff0c;需要扼要说明论文的目的、研究方法和最终结论。在发表学术论文时&#xff0c;很多重要刊物会要求作者将文章的摘要翻译成英文。那么&#xff0c;针对医学论文摘要翻译&#xff0c;中译英哪里比较专业&#xff1f; 专…

动态规划——路径问题:931.下降路径最小和

文章目录 题目描述算法原理1.状态表示&#xff08;经验题目&#xff09;2.状态转移方程3.初始化4.填表顺序5.返回值 代码实现CJava 题目描述 题目链接&#xff1a;931.下降路径最小和 关于这⼀类题&#xff0c;看过我之前的博客的朋友对于状态表示以及状态转移是⽐较容易分析…

pytorch基础: torch.unbind()

1. torch.unbind 作用 说明&#xff1a;移除指定维后&#xff0c;返回一个元组&#xff0c;包含了沿着指定维切片后的各个切片。 参数&#xff1a; tensor(Tensor) – 输入张量dim(int) – 删除的维度 2. 案例 案例1 x torch.rand(1,80,3,360,360)y x.unbind(dim2)print(&…

含义:理财风险等级R1、R2、R3、R4、R5

理财风险等级R1、R2、R3代表什么&#xff0c;为什么R1不保本&#xff0c;R2可能亏损 不尔聊投资https://author.baidu.com/home?frombjh_article&app_id1704141696580953 我们购买理财产品的时候&#xff0c;首先都会看到相关产品的风险等级。风险等级约定俗成有5级&…

树莓派4b测量心率、血氧浓度值

1.MAX30102心率和血氧浓度值连接图 2.MAX30102工作原理 工作原理 MAX30102采用PPG光电容积脉搏波描记法(PhotoPlethysmoGraphy)测量数据,微控制器对这些数据进行处理运算过后得到心率血氧数值,再通过I2C或UART接口输出,大大降低了传感器的使用难度和对主控的资源占用。同时…

力扣刷题--数组--第三天

今天再做两道二分查找的题目&#xff0c;关于二分查找的知识可看我前两篇博客。话不多说&#xff0c;直接开干&#xff01; 题目1&#xff1a;69.x 的平方根 题目详情&#xff1a;   给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。由于返回类型是整数&#…

Linux(openEuler、CentOS8)企业内网samba服务器搭建(Windows与Linux文件共享方案)

本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文) 目录 知识点实验1. 安装samba2. 启动smb服务并设置开机启动3. 查看服务器监听状态4. 配置共享访问用户5. 创建共享文件夹6. 修改配置文件7. 配置防火墙8. 使用windows…

组合模式(Composite)——结构型模式

组合模式(Composite)——结构型模式 组合模式是一种结构型设计模式&#xff0c; 你可以使用它将对象组合成树状结构&#xff0c; 并且能通过通用接口像独立整体对象一样使用它们。如果应用的核心模型能用树状结构表示&#xff0c; 在应用中使用组合模式才有价值。 例如一个场景…

如何在Ubuntu系统上定制文件系统

基于全志T507H处理器设计研发的OKT507-C开发板为例进行介绍。 Forlinx Desktop(Ubuntu)系统基于Ubuntu官方为嵌入式设备制作的操作系统-Lubuntu&#xff0c;该操作系统具备apt-get、ldd等常用的命令&#xff0c;若需要安装软件则直接apt-get在线安装即可&#xff0c;不需进行交…

LINUX 入门 4

LINUX 入门 4 day6 7 20240429 20240504 耗时&#xff1a;240min 课程链接地址 第4章 LINUX环境编程——实现线程池 C基础 第3节 #define里面的行不能乱空行&#xff0c;要换行就打\ typedef 是 C 和 C 中的一个关键字&#xff0c;用于为已有的数据类型定义一个新的名字。…

全面的Partisia Blockchain 生态 4 月市场进展解读

Partisia Blockchain 是一个以高迸发、隐私、高度可互操作性、可拓展为特性的 Layer1 网络。通过将 MPC 技术方案引入到区块链系统中&#xff0c;以零知识证明&#xff08;ZK&#xff09;技术和多方计算&#xff08;MPC&#xff09;为基础&#xff0c;共同保障在不影响网络完整…

Postgresql源码(128)深入分析JIT中的函数内联llvm_inline

相关 《Postgresql源码&#xff08;127&#xff09;投影ExecProject的表达式执行分析》 《LLVM的ThinLTO编译优化技术在Postgresql中的应用》 《LLVM&#xff08;5&#xff09;ORC实例分析》 1 JIT优化效果 create table t1(i int primary key, j int, k int); insert into t1…

鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙防掉坑指南

几点说明 kernel_liteos_a_note | 中文注解鸿蒙内核 是在 OpenHarmony 的 kernel_liteos_a 基础上给内核源码加上中文注解的版本.与官方源码按月保持同步,同步历史如下: 2021/10/09 – 增加性能优化模块perf,优化了文件映射模块2021/09/14 – common,extended等几个目录结构和M…

iOS ------ 内存五大分区

1&#xff0c;内存的概念&#xff1a; 虚拟内存&#xff08;Virtual Memory&#xff09;&#xff1a;虚拟内存是操作系统提供的一种机制&#xff0c;它使得应用程序能够访问超出物理内存限制的内存空间。虚拟内存将应用程序的内存地址空间分割成固定大小的页面&#xff08;Pag…

linux上如何排查JVM内存过高?

怎么排查JVM内存过高&#xff1f; 前言&#xff1a; 想必工作一两年以后的同学都会逐渐面临到&#xff0c;jvm等问题&#xff0c;但是可能苦于无法熟练的使用一些工具&#xff1b;本文将介绍几个比较常用分析工具的使用方法&#xff0c;带着大家一步步定位分析问题。 1、top 查…