基于顺序表实现通讯录

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.rhkb.cn/news/201690.html

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

相关文章

【精选】Ajax技术知识点合集

Ajax技术详解 Ajax简介 Ajax 即“Asynchronous Javascript And XML”&#xff08;异步 JavaScript 和 XML&#xff09;&#xff0c;是指一种创建 交互式、快速动态应用的网页开发技术&#xff0c;无需重新加载整个网页的情况下&#xff0c;能够更新页面局 部数据的技术。通过在…

Mac自带的看图如何连续查看多张图片

一、问题 mac看访达里的图片时&#xff0c;双击打开一张图片&#xff0c;然后按上下左右键都没法切换到另外的图片。而且也没找到像window一样单击缩略图可以看到预览图。其实是自己不懂得怎么使用&#xff0c;哈哈哈&#x1f602; 二、方法 2.1、图标方式 可以看到缩略图&a…

Java小游戏之飞翔的小鸟

游戏玩法&#xff1a;通过鼠标点击使小鸟上下移动穿过柱子并完成得分&#xff0c;小鸟碰到柱子或掉落到地面上都会结束游戏。 &#xff08;游戏内图片&#xff09; 下面是实现这个游戏的代码&#xff1a; Brid类&#xff1a; package bird;import org.omg.CORBA.IMP_LIMIT;im…

KyLin离线安装OceanBase

去OceanBase下载若干文件 1 首先安装ob-deploy-2.3.1-2.el7.x86_64.rpm rpm -ivh ob-deploy-2.3.1-2.el7.x86_64.rpm# 运行此命令的时候他会报错 RPM should not be used directly install RPM packages, use Alien instead! 这个需要用Alien去转换为deb的包&#xff0c;不…

使用PySpark 结合Apache SystemDS 进行信号处理分析 (离散傅立叶变换)的简单例子

文章大纲 简介 :什么是 SystemDS ?环境搭建与数据 准备数据预处理模型训练 与 结果评估参考文献简介 :什么是 SystemDS ? SystemDS is an open source ML system for the end-to-end data science lifecycle from data integration, cleaning, and feature engineering, ov…

skywalking中gateway的拓扑图没有出现

背景&#xff1a; 刚开始的时候gateway没有出现&#xff0c;后来百度说添加插件的jar包&#xff0c; apm-spring-cloud-gateway-2.1.x-plugin-8.15.0.jar apm-spring-webflux-5.x-plugin-8.15.0.jar 然后解决了gateway节点出来了&#xff0c; 但是&#xff1a;拓扑图却是User指…

prometheus热更新失败failed to reload config

一、问题描述 k8s部署的prometheus服务在请求热更新时报错: failed to reload config: one or more errors occurred while applying the new configuration (--config.file"/etc/prom/config/file/prometheus.yml")请求命令:curl -X POST http://monitor-cp-prom:…

【尚硅谷】第06章:随堂复习与企业真题(面向对象-基础)

第06章&#xff1a;随堂复习与企业真题&#xff08;面向对象-基础&#xff09; 一、随堂复习 1. &#xff08;了解&#xff09;面向过程 vs 面向对象 不管是面向过程、面向对象&#xff0c;都是程序设计的思路。面向过程&#xff1a;以函数为基本单位&#xff0c;适合解决简单…

CSM32RV003:国产高精度16位ADC低功耗RISC-V内核MCU

目录 高精度ADC工业应用工业数据采集应用CSM32RV003简介主要特性 高精度ADC工业应用 高精度ADC即高精度模数转换器&#xff0c;是一种能够将输入模拟信号转换为数字信号的芯片&#xff0c;在多种消费电子、工业、医疗和科研领域都有广泛应用。高精度ADC的主要特点是能够提供高…

基于单片机停车场环境监测系统仿真设计

**单片机设计介绍&#xff0c; 基于单片机停车场环境监测系统仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的停车场环境监测系统是一种利用单片机技术实现环境监测和数据处理的系统。它可以感知停车场的温湿…

依赖库:Ceres-solver-2.0.0安装

依赖库&#xff1a;Ceres-solver-2.0.0安装 前言安装ceres-solver-2.0.0验证 前言 Ceres Solver是谷歌开源的C非线性优化库&#xff0c;能够解决有约束或无约束条件下的非线性最小二乘问题。2010年之后大量的运用在谷歌的产品开发中&#xff0c;尤其在谷歌开源的cartographer中…

2023.11.20使用flask做一个简单图片浏览器

2023.11.20使用flask做一个简单图片浏览器 功能&#xff1a; &#xff08;1&#xff09;输入指定路径&#xff0c;打开文件夹 &#xff08;2&#xff09;判断文件格式为图片 &#xff08;3&#xff09;在前端进行预览 &#xff08;4&#xff09;使用bootstrap进行简单美化 ma…

Node.js入门指南(一)

目录 Node.js入门 什么是Node.js Node.js的作用 Node.js安装 Node.js编码注意事项 Buffer(缓冲器&#xff09; 定义 使用 fs模块 概念 文件写入 文件读取 文件移动与重命名 文件删除 文件夹操作 查看资源状态 路径问题 path模块 Node.js入门 什么是Node.js …

Gradle常用命令与参数依赖管理和版本决议

一、Gradle 常用命令与参数 本课程全程基于 Gradle8.0 环境 1、Gradle 命令 介绍 gradle 命令之前我们先来了解下 gradle 命令怎么在项目中执行。 1.1、gradlew gradlew 即 Gradle Wrapper&#xff0c;在学习小组的第一课时已经介绍过了这里就不多赘述。提一下执行命令&am…

Linux学习第44天:Linux 多点电容触摸屏实验(二):难忘记第一次牵你手的温存

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章的思维导图内容如下&#xff1a; 二、硬件原理图分析 三、实验程序编写 1、修改设备树 1&#xff09;、添加FT5426所使用的IO 一个复位 IO、一个中断 IO、…

合并区间问题

以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;intervals [[1,…

React函数组件渲染两次

渲染两次是因为react默认开启了严格模式 React.StrictMode标签作用&#xff1a; 1、识别不安全的生命周期 2、关于使用过时字符串 ref API 的警告 3、关于使用废弃的 findDOMNode 方法的警告 4、检测意外的副作用 5、检测过时的 context API 注释掉React.StrictMode即为关闭严…

Kotlin学习——hello kotlin 函数function 变量 类 + 泛型 + 继承

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…

01背包与完全背包学习总结

背包问题分类见下图 参考学习点击&#xff1a;代码随想录01背包讲解 01背包问题&#xff1a; 核心思路&#xff1a; 1、先遍历物品个数&#xff0c;再遍历背包容量。因为容量最先是最大的&#xff0c;往背包里放物品&#xff0c;所以背包容量在慢慢减少&#xff0c;但背包容量…

vue3+elementPlus登录向后端服务器发起数据请求Ajax

后端的url登录接口 先修改main.js文件 // 导入Ajax 前后端数据传输 import axios from "axios"; const app createApp(App) //vue3.0使用app.config.globalProperties.$http app.config.globalProperties.$http axios app.mount(#app); login.vue 页面显示部分…