基于顺序表实现通讯录

news2025/1/11 18:07:03

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看作下标的话相当于下标的最后一个位置+1
  int begin = pos + 1;
  while (begin < ps->size)
  {
    ps->a[begin - 1] = ps->a[begin];
    begin++;
  }
  ps->size--;
}

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

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

相关文章

Sentinel 监控数据持久化(mysql)

Sentinel 实时监控仅存储 5 分钟以内的数据&#xff0c;如果需要持久化&#xff0c;需要通过调用实时监控接口来定制&#xff0c;即自行扩展实现 MetricsRepository 接口&#xff08;修改 控制台源码&#xff09;。 本文通过使用Mysql持久化监控数据。 1.构建存储表&#xff08…

java-String

String 1. String引入 1.1 构造方法 public static void main1(String[] args) {//构造方法String s1 "hello world";String s2 new String("yuanwei");char[] values {a,b,c};String s3 new String(values);System.out.println(s1);System.out.printl…

看不惯AI版权作品被白嫖!Stability AI副总裁选择了辞职,曾领导开发Stable Audio

近日&#xff0c;OpenAI的各种大瓜真是让人吃麻了。 而就在Sam Altmam被开除前两天&#xff0c;可能没太多人注意到Stability AI副总裁Newton—Rex因看不惯StabilityAI在版权保护上的行为选择辞职一事。 大模型研究测试传送门 GPT-4传送门&#xff08;免墙&#xff0c;可直接…

记录一次因内存不足而导致hiveserver2和namenode进程宕机的排查

背景 最近发现集群主节点总有进程宕机&#xff0c;定位了大半天才找到原因&#xff0c;分享一下 排查过程 查询hiveserver2和namenode日志&#xff0c;都是正常的&#xff0c;突然日志就不记录了&#xff0c;直到我重启之后又恢复工作了。 排查各种日志都是正常的&#xff0…

windows搭建gitlab教程

1.安装gitlab 说明&#xff1a;由于公司都是windows服务器&#xff0c;这里安装以windows为例&#xff0c;先安装一个虚拟机&#xff0c;然后安装一个docker&#xff08;前提条件&#xff09; 1.1搜索镜像 docker search gitlab #搜索所有的docker search gitlab-ce-zh #搜索…

【css】Google第三方登录按钮样式修改

文章目录 场景前置准备修改样式官方属性修改样式CSS修改样式按钮的高度height和border-radiusLogo和文字布局 场景 需要用到谷歌的第三方登录&#xff0c;登录按钮有自己的样式。根据官方文档&#xff1a;概览 | Authentication | Google for Developers&#xff0c;提供两种第…

SPASS-ARIMA模型

基本概念 在预测中,对于平稳的时间序列,可用自回归移动平均(AutoRegres- sive Moving Average, ARMA)模型及特殊情况的自回归(AutoRegressive, AR)模型、移动平均(Moving Average, MA)模型等来拟合,预测该时间序列的未来值,但在实际的经济预测中,随机数据序列往往…

HarmonyOS ArkTS Video组件的使用(七)

概述 在手机、平板或是智慧屏这些终端设备上&#xff0c;媒体功能可以算作是我们最常用的场景之一。无论是实现音频的播放、录制、采集&#xff0c;还是视频的播放、切换、循环&#xff0c;亦或是相机的预览、拍照等功能&#xff0c;媒体组件都是必不可少的。以视频功能为例&a…

6-使用nacos作为注册中心

本文讲解项目中集成nacos&#xff0c;并将nacos作为注册中心使用的过程。本文不涉及nacos的原理。 1、项目简介 以一个演示项目为例&#xff0c;项目包含三个服务&#xff0c;调用及依赖如下图&#xff1a; 由图中可以看出&#xff0c;coupon-customer-serv为服务的消费者&a…

Python基础教程: sorted 函数

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 sorted 可以对所有可迭代的对象进行排序操作&#xff0c; sorted 方法返回的是一个新的 list&#xff0c;而不是在原来的基础上进行的操作。 从新排序列表。 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程…

9.4 Windows驱动开发:内核PE结构VA与FOA转换

本章将继续探索内核中解析PE文件的相关内容&#xff0c;PE文件中FOA与VA,RVA之间的转换也是很重要的&#xff0c;所谓的FOA是文件中的地址&#xff0c;VA则是内存装入后的虚拟地址&#xff0c;RVA是内存基址与当前地址的相对偏移&#xff0c;本章还是需要用到《内核解析PE结构导…

【论文阅读笔记】Emu Edit: Precise Image Editing via Recognition and Generation Tasks

【论文阅读笔记】Emu Edit: Precise Image Editing via Recognition and Generation Tasks 论文阅读笔记论文信息摘要背景方法结果额外 关键发现作者动机相关工作1. 使用输入和编辑图像的对齐和详细描述来执行特定的编辑2. 另一类图像编辑模型采用输入掩码作为附加输入 。3. 为…

第三节-Android10.0 Binder通信原理(三)-ServiceManager篇

1、概述 在Android中&#xff0c;系统提供的服务被包装成一个个系统级service&#xff0c;这些service往往会在设备启动之时添加进Android系统&#xff0c;当某个应用想要调用系统某个服务的功能时&#xff0c;往往是向系统发出请求&#xff0c;调用该服务的外部接口。在上一节…

Vue批量全局处理undefined和null转为““ 空字符串

我们在处理后台返回的信息&#xff0c;有的时候返回的是undefined或者null&#xff0c;这种字符串容易引起用户的误解&#xff0c;所以需要我们把这些字符串处理一下。 如果每个页面都单独处理&#xff0c;那么页面会很冗余&#xff0c;并且后期如果有修改容易遗漏&#xff0c…

生成式AI与大语言模型,东软已经准备就绪

伴随着ChatGPT的火爆全球&#xff0c;数以百计的大语言模型也争先恐后地加入了这一战局&#xff0c;掀起了一场轰轰烈烈的“百模大战”。毋庸置疑的是&#xff0c;继方兴未艾的人工智能普及大潮之后&#xff0c;生成式AI与大语言模型正在全球开启新一轮生产力革新的科技浪潮。 …

PostgreSQL (Hologres) 日期生成

PostgreSQL 生成指定日期下一个月的日期 &#xff08;在Hologres中&#xff0c;不支持递归查询&#xff09; SELECTto_char(T, YYYYMMDD)::int4 AS date_int,date(T) AS date_str,date_part(year, T)::int4 AS year_int,date_part(month, T)::int4 AS month_int,date_part(da…

中职组网络安全B模块-渗透提权2

任务五&#xff1a;渗透提权2 任务环境说明&#xff1a; 仅能获取xxx的IP地址 用户名&#xff1a;test&#xff0c;密码&#xff1a;123456 访问服务器主机&#xff0c;找到主机中管理员名称&#xff0c;将管理员名称作为Flag值提交&#xff1b; Flag:doyoudoyoudo 访问服…

使用Pytorch从零开始构建DCGAN

在本文中&#xff0c;我们将深入研究生成建模的世界&#xff0c;并使用流行的 PyTorch 框架探索 DCGAN&#xff08;生成对抗网络 (GAN) 的一种变体&#xff09;的实现。具体来说&#xff0c;我们将使用 CelebA 数据集&#xff08;名人面部图像的集合&#xff09;来生成逼真的合…

微服务学习|初识Docker、使用Docker、自定义镜像、DockerCompose、Docker镜像仓库

初识Docker 项目部署的问题 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题 依赖关系复杂&#xff0c;容易出现兼容性问题 开发、测试、生产环境有差异 Docker如何解决依赖的兼容问题的? 将应用的Libs (函数库)、Deps (依赖)配置与应用…

c语言:用迭代法解决递归问题

题目&#xff1a; 解释&#xff1a;题目的意思就是用迭代法的空间和时间复杂的太高了&#xff0c;需要我们减小空间与时间的复杂度&#xff0c;我就想到了迭代法&#xff0c;思路和代码如下&#xff1a; #include <stdio.h> //这里是递归法转迭代法 int main() {int x,i…