基于动态顺序表的应用——通讯录

文章目录

  • 顺序表的应用——基于动态顺序表实现通讯录
  • 一、顺序表的文件:
    • SeqList.h
    • SeqList.c
  • 二、通讯录的实现思路
  • 三、通讯录代码实现
    • 通讯录的初始化
    • 通讯录的销毁
    • 通讯录添加数据
    • 通过姓名查找联系人
    • 通讯录删除数据
    • 通讯录展示
    • 通讯录修改数据
    • 通讯录查找
    • 测试代码
  • 四、所有源代码
    • Contact.h
    • Contact.c
    • SeqList.h
    • SeqList.c
    • test.c

顺序表的应用——基于动态顺序表实现通讯录

一、顺序表的文件:

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "Contact.h"typedef peoInfo SLDateType;typedef struct SeqList
{SLDateType* arr;int size;int capacity;
}SL;//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);//扩容
void SLCheckCapacity(SL* ps);//头 插/删  尾 插/删
void SLPushFront(SL* ps, SLDateType x);
void SLPushBack(SL* ps, SLDateType x);void SLPopFront(SL* ps);
void SLPopBack(SL* ps);//指定位置前  插/ 删
void SLInsert(SL* ps, int pos, SLDateType x);
void SLErase(SL* ps, int pos);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}
//销毁
void SLDestroy(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}//扩容
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int NewCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDateType* tmp = (SLDateType*)realloc(ps->arr, NewCapacity * sizeof(SLDateType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = NewCapacity;}}//头插
void SLPushFront(SL* ps, SLDateType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size-1;i >= 0;i--){ps->arr[i + 1] = ps->arr[i];}ps->arr[0] = x;ps->size++;
}
//尾插
void SLPushBack(SL* ps, SLDateType x)
{assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}
//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0;i < ps->size-1;i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
//尾删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}
//指定位置前插
void SLInsert(SL* ps, int pos, SLDateType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);for (int i = ps->size-1;i >= pos;i--){ps->arr[i + 1] = ps->arr[i];}ps->arr[pos] = x;ps->size++;
}
//指定位置前删
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos;i < ps->size-1;i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

二、通讯录的实现思路

在实现通讯录的工程文件中一共包含了5个子文件
test.c:测试代码能否正常运行
SeqList.h:用于在实现顺序表的过程中定义结构体和各种方法
SeqList.c:实现在头文件中定义的方法
Contact.h:定义通讯录中实现功能的函数
Contact.c:实现头文件中定义的函数

在顺序表中,数组中存储的是单一的元素,在通讯录中,原数组中的元素变成了存储联系人数据的结构体,数组中的每个元素都是结构体类型,包括姓名、电话、性别、住址等,本质上是两个结构体的嵌套。

通讯录实质上就是顺序表,只不过是改了名字,我们只需要在实现顺序表的基础上给他起个别名通讯录即可。

在这里插入图片描述
这里用到了前置声明是因为头文件之间不可以互相包含,所以我们不可以将SeqList.h中的SL进行重命名,只能通过前置声明。
使用前置声明将Seqlist重命名为Contact,在该文件中我们并没有定义结构体SeqList,使用前置声明只是为了让编译器知道有这个结构体的存在,而无法直接对之前重命名过的SL再命名的原因是编译器不能识别到SL的存在,如果想要识别必须包含"SeqList.h",但是头文件相互包含会导致报错

我们用宏定义来表示数组的大小方便以后的调整(这些代码都是写在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);
}

通过姓名查找联系人

//通过姓名查找联系人
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];printf("请输入要删除的联系人的姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find != -1){SLErase(con, find);printf("删除成功!\n");}else{printf("要删除的联系人的数据不存在!\n");}
}

通讯录展示

//通讯录展示
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf(" %-4s %-4s %-4d %-4s %-4s\n",con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}

通讯录修改数据

//通讯录修改数据
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要修改的联系人的姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find == -1){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);
}

通讯录查找

//通讯录查找
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要修改的联系人的姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find == -1){printf("要修改的联系人的数据不存在!\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf(" %-4s %-4s %-4d %-4s %-4s\n",con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}

测试代码

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//菜单
void menu()
{printf("****************通讯录***********************\n");printf("******1.增加联系人	 2.删除联系人********\n");printf("******3.修改联系人	 4.查找联系人********\n");printf("******5.展示联系人	 0.  退出************\n");
}int main()
{int input = 0;Contact con;ContactInit(&con);do{menu();printf("请选择你的操作:\n");scanf("%d", &input);switch (input){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("退出通讯录...\n");break;default:printf("输入错误,请重新选择!\n");break;}} while (input != 0);ContactDestroy(&con);return 0;
}

四、所有源代码

Contact.h

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100//对于联系人数据 结构
//姓名 性别 年龄 电话 地址
typedef struct personInfo
{char name[NAME_MAX];char gender[GENDER_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 ContactShow(Contact* con);//通讯录查找
void ContactFind(Contact* con);

Contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
#include "SeqList.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);
}//通过姓名查找联系人
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];printf("请输入要删除的联系人的姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find != -1){SLErase(con, find);printf("删除成功!\n");}else{printf("要删除的联系人的数据不存在!\n");}
}//通讯录展示
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf(" %-4s %-4s %-4d %-4s %-4s\n",con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}//通讯录修改数据
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要修改的联系人的姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find == -1){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);
}//通讯录查找
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要修改的联系人的姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find == -1){printf("要修改的联系人的数据不存在!\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf(" %-4s %-4s %-4d %-4s %-4s\n",con->arr[find].name,con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "Contact.h"typedef peoInfo SLDateType;typedef struct SeqList
{SLDateType* arr;int size;int capacity;
}SL;//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);//扩容
void SLCheckCapacity(SL* ps);//头 插/删  尾 插/删
void SLPushFront(SL* ps, SLDateType x);
void SLPushBack(SL* ps, SLDateType x);void SLPopFront(SL* ps);
void SLPopBack(SL* ps);//指定位置前  插/ 删
void SLInsert(SL* ps, int pos, SLDateType x);
void SLErase(SL* ps, int pos);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}
//销毁
void SLDestroy(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}//扩容
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int NewCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDateType* tmp = (SLDateType*)realloc(ps->arr, NewCapacity * sizeof(SLDateType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = NewCapacity;}}//头插
void SLPushFront(SL* ps, SLDateType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size-1;i >= 0;i--){ps->arr[i + 1] = ps->arr[i];}ps->arr[0] = x;ps->size++;
}
//尾插
void SLPushBack(SL* ps, SLDateType x)
{assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}
//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0;i < ps->size-1;i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
//尾删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}
//指定位置前插
void SLInsert(SL* ps, int pos, SLDateType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);for (int i = ps->size-1;i >= pos;i--){ps->arr[i + 1] = ps->arr[i];}ps->arr[pos] = x;ps->size++;
}
//指定位置前删
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos;i < ps->size-1;i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//菜单
void menu()
{printf("****************通讯录***********************\n");printf("******1.增加联系人	 2.删除联系人********\n");printf("******3.修改联系人	 4.查找联系人********\n");printf("******5.展示联系人	 0.  退出************\n");
}int main()
{int input = 0;Contact con;ContactInit(&con);do{menu();printf("请选择你的操作:\n");scanf("%d", &input);switch (input){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("退出通讯录...\n");break;default:printf("输入错误,请重新选择!\n");break;}} while (input != 0);ContactDestroy(&con);return 0;
}

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

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

相关文章

R-tree总结

R树&#xff08;R-tree&#xff09;是一种树状数据结构&#xff0c;用于高效地索引和查询多维空间数据。它最常见的应用是在地理信息系统&#xff08;GIS&#xff09;和空间数据库中&#xff0c;用于管理和查询地理空间数据。下面是一个R树的简要总结&#xff0c;并结合一个实际…

永恒之蓝(ms17-010)复现

永恒之蓝 永恒之蓝&#xff08;Eternal Blue&#xff09;爆发于2017年4月14日晚&#xff0c;是一种利用Windows系统的SMB协议漏洞来获取系统的最高权限&#xff0c;以此来控制被入侵的计算机。甚至于2017年5月12日&#xff0c; 不法分子通过改造“永恒之蓝”制作了wannacry勒索…

计算机网络——CSMA/CD协议以及相关习题

目录 前言 引言 CSMA/CD协议 CSMA与CSMA/CD的区别 CSMA/CD流程 前言 本博客是博主用于复习计算机网络的博客&#xff0c;如果疏忽出现错误&#xff0c;还望各位指正。 引言 最早的以太网&#xff0c;许多计算机都连接在一根总线上工作——广播通信方式。 总线的特点想…

2024山东健博会/功能性食品/阿胶/酵素/营养品/肽产品展

2024第6届中国&#xff08;济南&#xff09;国际大健康产业博览会&#xff08;China-DJK山东健博会&#xff09; The 2024 sixth China (Jinan) International Big Health Industry Expo 时间&#xff1a;2024年05月27日—29日 场馆&#xff1a;济南黄河国际会展中心 主办&am…

vim配置 fzf 插件

要配置 fzf 插件&#xff0c;请按照以下步骤进行操作&#xff1a; 安装 fzf&#xff1a;首先&#xff0c;确保你已经安装了 fzf 工具。你可以从 fzf 的 GitHub 页面&#xff08;https://github.com/junegunn/fzf&#xff09;上找到详细的安装指南。 安装 fzf.vim 插件&#xf…

别让这6个UI设计雷区毁了你的APP!

一款成功的APP不仅仅取决于其功能性&#xff0c;更取决于用户体验&#xff0c;这其中&#xff0c;UI设计又至关重要。优秀的UI设计能够为用户带来直观、愉悦的交互体验&#xff0c;甚至让用户“一见钟情”&#xff0c;从而大大提高产品吸引力。 然而&#xff0c;有很多设计师在…

Python的基础知识学习路线2—运算符与变量类型(使用jupyter notebook进行操作:最全路线,每部分附有代码操作结果)

一、更改jupyter notebook 打开文件的位置 1、打开Anaconda Prompt终端&#xff0c;输入以下命令&#xff0c;创建配置文件&#xff1a;jupyter_notebook_config.py jupyter notebook --generate-config2、打开生成的配置文件 3、编辑配置文件jupyter_notebook_config.py&…

获取cookie的方式

获取Cookie的三种方式如下&#xff1a; 使用浏览器开发者工具。打开浏览器的开发者工具&#xff08;例如&#xff0c;Chrome的F12或右键检查&#xff09;&#xff0c;在登录或进行相关操作时&#xff0c;观察Network或XHR标签页中的请求和响应。在请求中查找包含Cookie的…

ssm045基于jsp的精品酒销售管理系统+jsp

精品酒销售管理系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于精品酒销售管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了精品酒销售管理系统&…

深度学习入门(2)

一。Matplotlib模块添加 Matplotlib是用于绘制图形的库&#xff0c;使用 Matplotlib 可以轻松地绘制图形和实现数据的可视化。 pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple 二、绘制简单图形 import numpy as np import matplotlib.pyplot as plt #…

三年了,期待下一个三年

第一个三年 时间好快&#xff0c;距离我发布我第一篇文章都已经三个年头了。 转眼也从大一新生变成了大四打工人。 在平台上发布博客&#xff0c;分享自己的项目、学习思路、解决的bug都带给我很多收获。 平台上的粉丝&#xff0c;阅读量等&#xff0c;也让我的简历更加出彩。…

SCP指令详细使用介绍

SCP&#xff08;Secure Copy Protocol&#xff09;是一种用于在计算机之间安全地传输文件的协议。它通过加密的方式在网络上安全地复制文件。SCP基于SSH&#xff08;Secure Shell&#xff09;协议&#xff0c;因此它提供了加密的连接和身份验证&#xff0c;确保数据在传输过程中…

约瑟夫问题---C++

今天来讲一道饶有名气的题目&#xff0c;约瑟夫问题 约瑟夫问题 这道题目有许多大佬用队列、递归、链表来解这道题目而这题的难度也确实非同小可&#xff01; 可是你们难道没有想过&#xff1f;用数组去解决吗&#xff1f;没错一维数组&#xff01;为了想出解决办法我掉了23根头…

Idea显示无法自动装配。找不到‘ xxx’类型的Bean

虽然只标红&#xff0c;不报错&#xff0c;但是看着非常别扭&#xff01; 原因&#xff1a; 当我们在使用Autowired注解的时候&#xff0c;默认requiredtrue,表示注入的时候bean必须存在&#xff0c;否则注入失败。 解决方案一&#xff1a; 在自动转配的注解后面添加(require…

ubuntu安装 Metasploit

在Ubuntu系统上安装Metasploit Framework可以通过几种方法实现&#xff0c;其中一种是使用Rapid7提供的官方安装包&#xff0c;另一种是通过系统的包管理器。以下是使用官方安装脚本的步骤&#xff0c;这通常能确保你获得最新版本的Metasploit。 使用官方安装脚本安装Metasplo…

Rockchip Android13 Vold(一):Native层

一:概述 Vold全称Volume Daemon是用于管理存储类设备的守护进程,负责接收驱动层设备挂载和卸载消息以及与Framework层之间的通信。Vold作为一个守护进程位于Android的Native Daemons层。 二:Vold框架图 三:Vold Sevice Android13的init.rc位于/system/etc/init/hw/其中使…

拷贝字符串---第十七天

1.myStrnpy(str,p,9); //把p地址的前9位字符串拷贝到str这边来 #include <stdio.h>char* myStrcpy(char *des,char *src) //目标地址&#xff0c;原地址 {if(des NULL || src NULL){return NULL;}char *bak des; //目标地址赋值给备份地址while(*src !\0){*des *…

xlsx-streame组件如何兼容poi5.x

问题描述 在poi和poi-ooxml版本为4.1.2时&#xff0c;使用xlsx-streamer处理大数据量的excel文件导入OOM问题&#xff0c;现在由于poi漏洞修复&#xff0c;需要升级到5.2.1&#xff0c;xlsx-streamer就不兼容高版本的poi了&#xff0c;poi-ooxml5.1.2提示XSSFReader.getShared…

Rust 实战练习 - 10. JSON、XML、YAML/TOML、Ini专题

配置文件 常见的配置文件有很多&#xff1a;JSON, Ini, XML, TOML, YAML … 目标&#xff1a; JSON/YAML/TOMLIniXML Rust中序列化用的最多的是 serde, 依赖它&#xff0c;有很多出色的第三方库可以使用。 其中&#xff0c;serde本身支持JSON/YAML/TOML/JSON5…多种&#…

反转字符串

. - 力扣&#xff08;LeetCode&#xff09; 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 你可以假设数组…