基于顺序表实现通讯录

1.功能实现

功能要求
1)至少能够存储100个人的通讯信息
2)能够保存用户信息:名字、性别、年龄、电话、地址等
3)增加联系人信息
4)删除指定联系人
5)查找制定联系人
6)修改指定联系人
7)显联系人信息

2.与顺序表的关系

在这里插入图片描述

3.代码实现

1.通讯录基本结构Contact.h

在这里插入图片描述
Contact.h文件代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 15
#define ADDR_MAX 100//创建通讯录的结构
typedef struct ContactInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}CInfo;typedef struct SeqList contact;//此处相当于把顺序表的名字改为通讯录,也可以理解为我把顺序表的SL改为了contact,不容易搞混
//因为并没有调用"SeqList.h"里面的数据或者函数,所以这里不需要调用void ContactInit(contact* pcon);    //通讯录的创建
void ContactDestroy(contact* pcon); //通讯录的销毁void ContactAdd(contact* *pcon);    //添加联系人
void ContactDel(contact* pcon);     //删除联系人void ContactModify(contact* pcon);  //修改联系人
void Contactshow(contact* pcon);    //打印联系人void ContactFind(contact* pcon);    //查找联系人

2.基于通讯录SqList.h文件的改进

需要把顺序表的数据类型改为通讯录的结构体,这里就体现了之前在顺序表把int类型通过typedef声明为SLDataType的好处,可以很方便的更换顺序表的类型,不用一个个改。

在这里插入图片描述

SqList.h文件代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"typedef CInfo SLDataType;
//typedef int SLDataType;
//把顺序表的数据结构改为通讯录的结构体类型typedef struct SeqList
{SLDataType* a;int size;       // 有效数据int capacity;   // 空间容量
}SL;void SLInit(SL* ps);    // 数据表初始化
void SLDestroy(SL* ps); // 数据表销毁void SLPushFront(SL* ps, SLDataType x); // 头插
void SLPushBack(SL* ps, SLDataType x);  // 尾插void SLPopFront(SL* ps);  // 头删
void SLPopBack(SL* ps);   // 尾删void SLCheckCapacity(SL* ps); // 检查内存是否足够,不够就扩容。
void SLprintf(SL* ps);  // 数据表打印void SLInsert(SL* ps, int pos, SLDataType x);  //任意下标位置的插入
void SLErase(SL* ps, int pos);  //任意下标位置的删除

3通讯录运行文件Contact.c

1. 通讯录的创建ContactInit

只需要调用顺序表的初始化就可以啦

void ContactInit(contact* pcon)
{SLInit(pcon);
}

2.通讯录的销毁ContactDestroy

一样的道理,顺序表都销毁了,基于它的通讯录还好存在吗?所以自己调用顺序表的销毁就OK啦

void ContactDestroy(contact* pcon)
{SLDestroy(pcon);
}

3.添加联系人

到这里就需要创建个通讯录结构体(info),然后输入值到通讯录的结构体中,随便打印个提示界面,然后记得调用顺序表的尾插操作,通过info把数据插入到顺序表中,因为顺序表的数据类型是CInfo也就是struct ContactInfo,所以并不冲突。
在这里插入图片描述

void ContactAdd(contact** pcon)
{CInfo info;printf("请输入联系人的姓名:\n");scanf("%s", info.name);printf("请输入联系人的性别:\n");scanf("%s", info.sex);printf("请输入联系人的年龄:\n");scanf("%d", &info.age);printf("请输入联系人的电话:\n");scanf("%s", info.tel);printf("请输入联系人的住址:\n");scanf("%s", info.addr);SLPushBack(pcon, info);
}

4.删除联系人

有了创建自然就有删除,但是删除删除哪里了,所以还要个查找操作

int FindByName(contact* pcon,char name)
{for (int i = 0; i < pcon->size; pcon->size++){if (strcmp(pcon->size,name)==0){return i;}}return -1;
}

先输入用户名,然后通过用户名进行查找操作,找到了就调用顺序表的删除操作

void ContactDel(contact* pcon)
{printf("请输入要删除的用户的名称:\n");char name[NAME_MAX];scanf("%s", &name);int findidex = FindByName(pcon,name);SLPopBack(pcon);if (findidex < 0){printf("要删除的联系人不存在");return;}SLErase(pcon, findidex);
}

5.修改联系人

通过查找,

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

6.打印联系人

void Contactshow(contact* pcon)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");for(int i = 0; i < pcon->size; i++){printf("%-4s %-4s %-4d %-4s %-4s\n",pcon->a[i].name,pcon->a[i].sex,pcon->a[i].age,pcon->a[i].tel,pcon->a[i].addr);}
}

7.查找联系人

void ContactFind(contact* pcon)
{char name[NAME_MAX];printf("请输入要查找的用户名称:\n");scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("该联系人不存在\n");return;}printf("%s %s %d %s %s\n",pcon->a[find].name,pcon->a[find].sex,pcon->a[find].age,pcon->a[find].tel,pcon->a[find].addr);
}

完整代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void ContactInit(contact* pcon)
{SLInit(pcon);
}
void ContactDestroy(contact* pcon)
{SLDestroy(pcon);
}void ContactAdd(contact** pcon)
{CInfo info;printf("请输入联系人的姓名:\n");scanf("%s", info.name);printf("请输入联系人的性别:\n");scanf("%s", info.sex);printf("请输入联系人的年龄:\n");scanf("%d", &info.age);printf("请输入联系人的电话:\n");scanf("%s", info.tel);printf("请输入联系人的住址:\n");scanf("%s", info.addr);SLPushBack(pcon, info);
}int FindByName(contact* pcon,char name)
{for (int i = 0; i < pcon->size; pcon->size++){if (strcmp(pcon->size,name)==0){return i;}}return -1;
}void ContactDel(contact* pcon)
{printf("请输入要删除的用户的名称:\n");char name[NAME_MAX];scanf("%s", &name);int findidex = FindByName(pcon,name);SLPopBack(pcon);if (findidex < 0){printf("要删除的联系人不存在");return;}SLErase(pcon, findidex);
}void ContactModify(contact* pcon)
{printf("请输入要修改的用户名称:\n");char name[NAME_MAX];scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("要修改的用户不存在!\n");return;}printf("请输入新的用户名称:\n");scanf("%s", pcon->a[find].name);printf("请输入新的用户性别:\n");scanf("%s", pcon->a[find].sex);printf("请输入新的用户年龄:\n");scanf("%s", pcon->a[find].age);printf("请输入新的用户电话:\n");scanf("%s", pcon->a[find].tel);printf("请输入新的用户地址:\n");scanf("%s", pcon->a[find].addr);printf("修改成功\n");
}void Contactshow(contact* pcon)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");for(int i = 0; i < pcon->size; i++){printf("%-4s %-4s %-4d %-4s %-4s\n",pcon->a[i].name,pcon->a[i].sex,pcon->a[i].age,pcon->a[i].tel,pcon->a[i].addr);}
}void ContactFind(contact* pcon)
{char name[NAME_MAX];printf("请输入要查找的用户名称:\n");scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("该联系人不存在\n");return;}printf("%s %s %d %s %s\n",pcon->a[find].name,pcon->a[find].sex,pcon->a[find].age,pcon->a[find].tel,pcon->a[find].addr);
}

4SeqList.c顺序表的基本函数

此处存放顺序表的基本操作函数,所以无需修改,与通讯录有关的操作存放在Contact.c文件中

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void SLCheckCapacity(SL* ps)  // 检查内存是否足够,不够就扩容。
{if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newCapacity;}
}void SLprintf(SL* ps)   // 数据表打印
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}void SLInit(SL* ps)     // 数据表初始化
{assert(ps);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}void SLDestroy(SL* ps)  // 数据表销毁
{assert(ps);if (ps->a != NULL){free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;}
}void SLPushFront(SL* ps, SLDataType x)  // 头插
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}void SLPushBack(SL* ps, SLDataType x)   // 尾插
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size++] = x;
}void SLPopFront(SL* ps) // 头删
{assert(ps);assert(ps->size > 0);int begin = 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}void SLPopBack(SL* ps)  // 尾删
{assert(ps);assert(ps->size > 0);ps->size--;
}// pos是下标
void SLInsert(SL* ps, int pos, SLDataType x)  // 任意下标位置的插入
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
void SLErase(SL* ps, int pos)    // 任意下标位置的删除
{assert(ps);assert(pos >= 0 && pos < ps->size);   // 这里删除不能用等于ps->size,ps->size看作下标的话相当于下标的最后一个位置+1int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}

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

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

相关文章

Android Spannable 使用​注意事项

1、当前示例中间的 "评论"&#xff0c;使用SpannableStringBuilder实现&#xff0c;点击评论会有高亮效果加粗&#xff0c;但再点击其它Bar时无法恢复默认样式。 2、因为SpannableString或SpannableStringBuilder中的效果是叠加的&#xff0c;恢复默认样式需要先移除…

基于高质量训练数据,GPT-4 Turbo更出色更强大

11月7日消息&#xff0c;OpenAI在首届开发者大会上正式推出了GPT-4 Turbo。 与GPT-4相比&#xff0c;GPT-4 Turbo主要有6方面的提升&#xff1a; 1、扩展下文对话长度&#xff1a;GPT4最大只能支持8k的上下文长度&#xff08;约等于6000个单词&#xff09;&#xff0c;而GPT-4…

python爬虫HMAC加密案例:某企业信息查询网站

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行 atob(‘aHR0cHM6Ly93d3cucWNjLmNvbS93ZWIvc2VhcmNoP2tleT0lRTQlQjglODclRTglQkUlQkUlRTklOUI…

广告机/商业显示屏_基于MT878安卓主板方案

安卓主板在广告机领域扮演着重要的角色。无论是在商场、车站、酒店、电梯、机场还是高铁站&#xff0c;LED广告机广泛应用&#xff0c;并通过不同方式进行播放和管理。 广告机/商业显示屏_基于MT878安卓主板方案 基于MT8788安卓主板方案的广告机采用了联发科MT8788八核芯片方案…

nint和Pattern matching介绍(C#)

nint 最近看C# 9.0时&#xff0c;发现一个有意思的关键词&#xff0c;就是nint&#xff0c;第一次看到这个&#xff0c;于是好奇心爆棚&#xff0c;就去实际操作了一下。 nint i 1000; Console.WriteLine("i{0}", i);实际结果与int的结果是一样的&#xff0c;那为什…

HCIP-四、MUX-vlanSuper-vlan+端口安全

四、MUX-vlan&Super-vlan端口安全 MUX-vlan实验拓扑实验需求及解法1. 在SW1/2/3分别创建vlan10 20 30 402. SW1/2/3之间使用trunk链路&#xff0c;仅允许vlan10 20 30 40 通过。3. SW与PC/Server之间使用access链路。4. ping验证&#xff1a; Super-vlan端口安全实验拓扑实…

实在智能携“TARS大模型”入选“2023中国数据智能产业AI大模型先锋企业”

近日&#xff0c;由数据猿与上海大数据联盟联合主办的“2023企业数智化转型升级发展论坛”在上海圆满收官。 论坛颁奖典礼上&#xff0c;《2023中国数据智能产业AI大模型先锋企业》等六大榜单正式揭晓&#xff0c;旨在表彰在AI领域为数智化升级取得卓越成就和突出贡献的企业&am…

基于C#实现优先队列

一、堆结构 1.1性质 堆是一种很松散的序结构树&#xff0c;只保存了父节点和孩子节点的大小关系&#xff0c;并不规定左右孩子的大小&#xff0c;不像排序树那样严格&#xff0c;又因为堆是一种完全二叉树&#xff0c;设节点为 i,则 i/2 是 i 的父节点&#xff0c;2i 是 i 的…

Doris动态分区(十四)

动态分区是在 Doris 0.12 版本中引入的新功能。旨在对表级别的分区实现生命周期管理&#xff08;TTL&#xff09;&#xff0c;减少用户的使用负担。 目前实现了动态添加分区及动态删除分区的功能。动态分区只支持 Range 分区。 原理 在某些使用场景下&#xff0c;用户会将表…

【中间件】服务化中间件理论intro

中间件middleware 内容管理 intro服务化middleware架构注册中心intro服务治理系统intro 本文主要intro服务化中间件的探讨 去年cfeng写了一篇博客走马观花般阐述了Spring Cloud下面的各种中间件&#xff0c;连深入使用都谈不上&#xff0c;只能说intro&#xff0c;在实际work中…

LabVIEW中将SMU信号连接到PXI背板触发线

LabVIEW中将SMU信号连接到PXI背板触发线 本文介绍如何将信号从PXI&#xff08;e&#xff09;SMU卡路由到PXI&#xff08;e&#xff09;机箱上的背板触发线。该过程涉及使用NI-DCPowerVI将SMU信号导出到PXI_TRIG线上。 在继续操作之前&#xff0c;请确保在开发PC上安装了兼容版…

python二叉树链树_树的链式存储结构

二叉链树是一种树状数据结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;分别称为左子节点和右子节点。每个节点包含一个数据元素和指向其左右子节点的指针。二叉链树可以是空树&#xff0c;也可以是具有以下特点的非空树&#xff1a; 1. 每个节点最多有两个子节点。…