C顺序表:通讯录

目录

前言

通讯录数据结构

通讯录初始化 

查找名字

增加联系人

删除联系人

展示所有联系人

查找联系人

修改信息

销毁通讯录

完整通讯录代码


前言

数据结构中的顺序表如果已经学会了,那么我们就可以基于顺序表来完成一个通讯录了

通讯录其实我们使用前面学习过的顺序表就能完成不过,相比较来说,前面的顺序表就是个整型数组,但通讯录就是一个多信息的自定义类型了

如果没了解过顺序表的可以看看我前篇博客

C数据结构:顺序表-CSDN博客

下面直接来开始完成我们的通讯录吧

通讯录数据结构

typedef struct PersonInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;typedef PeoInfo SLDataType;
//typedef int SLDataType;typedef struct SeqList
{SLDataType* a;int size;     // 有效数据个数int capacity; // 空间容量
}SL;

通讯里结构体里定义了五个成员,名字、性别、年龄、电话、地址

数组大小使用了宏定义,因为有需要更改的时候就比较方便,不需要一个个去更改

下面就开始通讯录的实现吧

如果文件中有顺序表的.c文件,请务必屏蔽以下函数,否则会引起报错

 

 

1. SLPrint函数中含有 %d,%d是整型的占位符,如果我们需要打印自定义类型是不能使用%d占位符的

2. SLFind函数中if的判断条件 ps->a[i] == x这个有错误,我们的a数组的类型是个自定义类型,该类型里含有5个成员,怎么能直接让两个自定义类型直接比较呢?

通讯录初始化 

void InitContact(contact* con)
{SLInit(con);
}

初始化一个联系人就和初始化一个顺序表一样,所以直接使用顺序表的函数对里面的参数con进行初始化即可 

查找名字

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

为什么要先写查找名字呢?

因为我们后面删除联系人、查找联系人、修改联系人都会使用到这个模板,如果都按一个模板来写会显得代码很冗余,并且浪费时间,所以我们直接写一个函数就可以有效的解决这个问题

我们直接遍历整个联系人a数组里面的名字,当名字匹配的时候,我们就返回它的下标,否则出了循环之后说明没找到名字,则返回-1

我们不能直接写

con->a[i].name == name作为if语句的条件

因为这个name是个char类型的数组名,而数组名是地址,用地址来比较是得不出答案的,所以需要借助到string.h里的strcmp函数 

对string.h库函数有兴趣的可以看看我前面的博客 

ctype.h的了解string.h库函数中各个函数的使用和模拟实现-CSDN博客

增加联系人

void AddContact(contact* con)
{assert(con);PeoInfo c;printf("请输入姓名:>");scanf("%s", c.name);printf("请输入性别:>");scanf("%s", c.sex);printf("请输入年龄:>");scanf("%d", &c.age);printf("请输入电话:>");scanf("%s", c.tel);printf("请输入地址:>");scanf("%s", c.addr);SLPushBack(con, c);
}
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps); //检查数组大小是否足够ps->a[ps->size] = x;ps->size++;
}

 先是定义了一个通讯录c变量,并把我们需要增加的联系人的信息先暂时放到c中

最后使用顺序表里的SLPushBack函数将这些信息放到我们的通讯录数组中即可

删除联系人

void DelContact(contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要删除的姓名:>");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0){printf("要删除的用户不存在!\n");return;}SLErase(con, pos);printf("删除成功\n");
}
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos <= ps->size && pos >= 0);assert(ps->size > 0);for (int i = pos; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

先定义了一个name数组接收我们要删除的人的名字,然后使用我们前面写到的FindByName找到这个名字的下标,最后使用SLErase函数删除掉通讯录数组这个下标所在的位置即可

展示所有联系人

void ShowContact(contact* con)
{assert(con);//打印表头printf("姓名\t性别\t年龄\t电话\t地址\n");for (int i = 0; i < con->size; i++){printf("%s\t%s\t%d\t%s\t%s\n", con->a[i].name,con->a[i].sex,con->a[i].age,con->a[i].tel,con->a[i].addr);}
}

展示这一步就是给使用者看的,为了美观对齐所以在每一个信息的后面加了一个\t

最后用for循环遍历通讯录数组打印所有的信息即可

查找联系人

void FindContact(contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要查找的姓名:>");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0){printf("查找的用户不存在!\n");return;}printf("查找成功\n");printf("%s\t%s\t%d\t%s\t%s\t", con->a[pos].name,con->a[pos].sex,con->a[pos].age,con->a[pos].tel,con->a[pos].addr);
}

 还是一样先找到名字所在通讯录数组的下标,如果能找到说明联系人存在,利用下标打印出该人的信息即可

修改信息

void ModifyContact(contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要修改的姓名:>");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0){printf("查找的用户不存在!\n");return;}printf("请输入姓名:>");scanf("%s", con->a[pos].name);printf("请输入性别:>");scanf("%s", con->a[pos].sex);printf("请输入年龄:>");scanf("%d", &con->a[pos].age);printf("请输入电话:>");scanf("%s", con->a[pos].tel);printf("请输入地址:>");scanf("%s", con->a[pos].addr);printf("修改成功\n");
}

也是一样先查找该名字所在通讯录数组的下标,然后重新使用scanf输入该下标的所有信息即可 

销毁通讯录

void DestroyContact(contact* con)
{assert(con);SLDestroy(con);
}
void SLDestroy(SL* ps)
{assert(ps);if (ps->a){free(ps->a);}ps->a = NULL;ps->capacity = ps->size = 0;
}

销毁直接用顺序表中的SLDestroy实现即可

完整通讯录代码

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100//前置声明
typedef struct SeqList contact;//用户数据
typedef struct PersonInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;//初始化通讯录
void InitContact(contact* con);//添加通讯录数据
void AddContact(contact* con);//删除通讯录数据
void DelContact(contact* con);//展示通讯录数据
void ShowContact(contact* con);//查找通讯录数据
void FindContact(contact* con);//修改通讯录数据
void ModifyContact(contact* con);//销毁通讯录数据
void DestroyContact(contact* con);typedef PeoInfo SLDataType;
//typedef int SLDataType;// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* a;int size;     // 有效数据个数int capacity; // 空间容量
}SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);//头部插入删除 / 尾部插入删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);void SLInit(SL* ps)
{assert(ps);ps->a = NULL;ps->capacity = ps->size = 0;
}void SLDestroy(SL* ps)
{assert(ps);if (ps->a){free(ps->a);}ps->a = NULL;ps->capacity = ps->size = 0;
}//void SLPrint(SL* ps)
//{
//	assert(ps);
//
//	for (int i = 0; i < ps->size; i++)
//	{
//		printf("%d ", ps->a[i]);
//	}
//	printf("\n");
//}void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->capacity == 0){ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);ps->capacity = 4;}if (ps->capacity == ps->size && ps->capacity != 0){//定义tmp接收防止扩容失败原数组被覆盖SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(SLDataType));if (tmp == NULL){perror("realloc fail!\n");return;}//扩容成功ps->a = tmp;ps->capacity *= 2;}
}void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}void SLPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);ps->size--;
}void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size - 1; i >= 0; i--){ps->a[i + 1] = ps->a[i];}ps->a[0] = x;ps->size++;
}void SLPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);for (int i = 0; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos <= ps->size && pos >= 0);SLCheckCapacity(ps);for (int i = ps->size; i >= pos; i--){ps->a[i + 1] = ps->a[i];}ps->a[pos] = x;ps->size++;
}void SLErase(SL* ps, int pos)
{assert(ps);assert(pos <= ps->size && pos >= 0);assert(ps->size > 0);for (int i = pos; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}//int SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->a[i] == x)
//		{
//			return i;
//		}
//	}
//
//	return -1;
//}void InitContact(contact* con)
{SLInit(con);
}void AddContact(contact* con)
{assert(con);PeoInfo c;printf("请输入姓名:>");scanf("%s", c.name);printf("请输入性别:>");scanf("%s", c.sex);printf("请输入年龄:>");scanf("%d", &c.age);printf("请输入电话:>");scanf("%s", c.tel);printf("请输入地址:>");scanf("%s", c.addr);SLPushBack(con, c);
}int FindByName(contact* con, char name[])
{assert(con);for (int i = 0; i < con->size; i++){if (strcmp(con->a[i].name, name) == 0){return i;}}return -1;
}void DelContact(contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要删除的姓名:>");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0){printf("要删除的用户不存在!\n");return;}SLErase(con, pos);printf("删除成功\n");
}void ShowContact(contact* con)
{assert(con);//打印表头printf("姓名\t性别\t年龄\t电话\t地址\n");for (int i = 0; i < con->size; i++){printf("%s\t%s\t%d\t%s\t%s\n", con->a[i].name,con->a[i].sex,con->a[i].age,con->a[i].tel,con->a[i].addr);}
}void FindContact(contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要查找的姓名:>");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0){printf("查找的用户不存在!\n");return;}printf("查找成功\n");printf("%s\t%s\t%d\t%s\t%s\t", con->a[pos].name,con->a[pos].sex,con->a[pos].age,con->a[pos].tel,con->a[pos].addr);
}void ModifyContact(contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要修改的姓名:>");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0){printf("查找的用户不存在!\n");return;}printf("请输入姓名:>");scanf("%s", con->a[pos].name);printf("请输入性别:>");scanf("%s", con->a[pos].sex);printf("请输入年龄:>");scanf("%d", &con->a[pos].age);printf("请输入电话:>");scanf("%s", con->a[pos].tel);printf("请输入地址:>");scanf("%s", con->a[pos].addr);printf("修改成功\n");
}void DestroyContact(contact* con)
{assert(con);SLDestroy(con);
}void Test2()
{contact c;InitContact(&c);AddContact(&c);AddContact(&c);ShowContact(&c);//DelContact(&c);ModifyContact(&c);ShowContact(&c);FindContact(&c);DestroyContact(&c);
}int main()
{//Test1();Test2();return 0;
}

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

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

相关文章

红蓝色WordPress外贸建站模板

红蓝色WordPress外贸建站模板 https://www.mymoban.com/wordpress/5.html

Mysql底层原理十:Redo log

3.7 Redo log Redo log记录的是物理日志&#xff0c;具体就是哪个表空间&#xff0c;哪个数据页&#xff0c;哪个偏移量&#xff0c;改了几个字节&#xff0c;改成什么表空间号数据页号偏移量修改几个字节的值具体的值 3.7.1 Redo block &#xff08;批处理缓存&#xff09;…

nginx支持的多种负载均衡策略

目录 1.轮询&#xff08;默认&#xff09; 2. ip_hash 3. 加权轮询&#xff08;weight&#xff09; 4. fair&#xff08;第三方&#xff09; 5. 最少连接&#xff08;least_conn&#xff09; 1.轮询&#xff08;默认&#xff09; 将请求依次分配给每个服务器&#xff0c;确…

DeepSort行人车辆识别系统(实现目标检测+跟踪+统计)

文章目录 1、前言2、源项目实现功能3、运行环境4、如何运行5、运行结果6、遇到问题7、使用框架8、目标检测系列文章 1、前言 1、本文基于YOLOv5DeepSort的行人车辆的检测&#xff0c;跟踪和计数。 2、该项目是基于github的黄老师傅&#xff0c;黄老师傅的项目输入视频后&#x…

区块链相关概念

区块链是什么&#xff0c;就算是做计算机技术开发的程序员&#xff0c;100个当中都没有几个能把这个概念理解明白&#xff0c;更不要说讲清楚了。那对于普通人来说&#xff0c;就更扯了。 除了“挖矿”表面意思似乎比较好理解外&#xff0c;其他的基础概念真TMD绕。 去中心化、…

坚持十天做完Python入门100题第一天

坚持十天做完Python入门100题第一天 第1题 变量更新第2题 变量命名规则第3题 类型错误第4题 序列索引第5题 序列切片第6题 负数切片第7题 Range函数 第1题 变量更新 解析&#xff1a;Python代码的读取和执行是由上至下的&#xff0c;变量n一开始被赋值为1&#xff0c;但被更新了…

CLIP模型 图片问答

先简短介绍一下CLIP模型&#xff1a; CLIP (Contrastive Language–Image Pretraining) 是由 OpenAI 开发的先进的多模态视觉模型&#xff0c;结合了图像和文本处理能力。 CLIP 模型的主要特色在于它不仅可以理解图像&#xff0c;同时也能理解描述这些图像的文本。通过这样的方…

深度学习理论基础(七)Transformer编码器和解码器

学习目录&#xff1a; 深度学习理论基础&#xff08;一&#xff09;Python及Torch基础篇 深度学习理论基础&#xff08;二&#xff09;深度神经网络DNN 深度学习理论基础&#xff08;三&#xff09;封装数据集及手写数字识别 深度学习理论基础&#xff08;四&#xff09;Parse…

数据仓库面试总结

文章目录 1.什么是数据仓库&#xff1f;2.ETL是什么&#xff1f;3.数据仓库和数据库的区别&#xff08;OLTP和OLAP的区别&#xff09;4.数据仓库和数据集市的区别5.维度分析5.1 什么是维度&#xff1f;5.2什么是指标&#xff1f; 6.什么是数仓建模&#xff1f;7.事实表7.维度表…

Qt使用iostream的cout

在QT想使用iostream的cout。 参考以下博客&#xff1a; &#xff08;转载&#xff09;Qt中使用cout输出的方法 pro里加上; CONFIG console勾选 Run in Terminal clean工程&#xff0c;重新构建 上面是cout的&#xff0c;下面是我的另一个函数的qDebug输出的。

【动态规划-状态压缩dp】【蓝桥杯备考训练】:毕业旅行问题、蒙德里安的梦想、最短Hamilton路径、国际象棋、小国王【已更新完成】

目录 1、毕业旅行问题&#xff08;今日头条2019笔试题&#xff09; 2、蒙德里安的梦想&#xff08;算法竞赛进阶指南&#xff09; 3、最短Hamilton路径&#xff08;《算法竞赛进阶指南》&模板&#xff09; 4、国际象棋&#xff08;第十二届蓝桥杯省赛第二场C A组/B组&#…

vue+springboot多角色登录

①前端编写 将Homeview修改为manager Manager&#xff1a; <template><div><el-container><!-- 侧边栏 --><el-aside :width"asideWidth" style"min-height: 100vh; background-color: #001529"><div style"h…

Jetpack Compose -> 状态机制的背后秘密

前言 上一章我们讲解了 Jetpack Compose 的无状态、状态提升、单向数据流 本章我们讲解下状态机制的背后秘密 List 前面我们讲过&#xff0c;通过 by mustableStateOf() 就可以被 Compose 自动订阅了&#xff1b;我们前面是通过 String 类型进行的自动订阅&#xff0c;那么换成…

C语言 | Leetcode C语言题解之第13题罗马数字转整数

题解&#xff1a; 题解&#xff1a; int romanToInt(char* s) {int symbolValues[26];symbolValues[I - A] 1;symbolValues[V - A] 5;symbolValues[X - A] 10;symbolValues[L - A] 50;symbolValues[C - A] 100;symbolValues[D - A] 500;symbolValues[M - A] 1000;int a…

基于Spring boot+Vue的业余排球俱乐部会员管理系统

5 系统功能模块的具体实现 5.1超级会员角色 5.1.1 登录 超级管理员登录通过用户名和密码去数据库查询用户表&#xff0c;该名称是否在用户表中存在&#xff0c;如果存在&#xff0c;则通过用户名和密码查询密码是否正确&#xff0c;然后吧用户的信息存在jwt的负载里&#xf…

【学习】渗透测试有哪些重要性

随着信息技术的迅猛发展&#xff0c;网络安全问题日益凸显。渗透测试作为网络安全防御的重要手段之一&#xff0c;旨在模拟黑客攻击&#xff0c;发现并修复潜在的安全漏洞&#xff0c;提高网络系统的安全性。本文将介绍渗透测试的概念、重要性、实施步骤及实践案例&#xff0c;…

PPT 操作

版式 PPT中&#xff0c;巧妙使用母版&#xff0c;可以提高效率。 双击母版&#xff0c;选择其中一个版式&#xff0c;插入装饰符号。 然后选择关闭。 这个时候&#xff0c;在该版式下的所有页面&#xff0c;就会出现新加入的符号。不在该版式下的页面&#xff0c;不会出现新加…

springboot 反射调用ServiceImpl时报错:java.lang.NullPointerExceptio、,mapper为null【解决方法】

springboot 反射调用ServiceImpl时报错&#xff1a;java.lang.NullPointerException、mapper为null【解决方法】 问题描述问题分析解决方案创建SpringBootBeanUtil编写调用方法 executeMethod调用 总结 问题描述 在使用Spring Boot时&#xff0c;我们希望能够通过反射动态调用…

0基础安装配置Linux-ubuntu环境

Vmtools的安装参见 0基础教你安装VM 17PRO-直接就是专业许可证版_vm17许可证-CSDN博客 在vmtools中安装ubuntu 等待安装 这时候发现没有继续按钮&#xff0c;我们关闭这个界面&#xff0c;进入系统中&#xff0c;先更改分辨率 点击这个三角&#xff0c;因为还么有安装成功&am…

初识ES(ES的基本概念、倒排索引、索引和文档的CRUD)

1、ES是什么&#xff1f; 一个开源的分布式搜索引擎&#xff0c;可以用来实现搜索、日志统计、分析、系统监控等功能。ES的底层是基于Lucene实现的。 Lucene是一个Java语言的搜索引擎类库。 什么是elastic stack&#xff08;ELK&#xff09;&#xff1f; elasticsearch。存储、…