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

文章目录

  • 顺序表的应用——基于动态顺序表实现通讯录
  • 一、顺序表的文件:
    • 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,一经查实,立即删除!

相关文章

永恒之蓝(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;许多计算机都连接在一根总线上工作——广播通信方式。 总线的特点想…

别让这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&…

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;也让我的简历更加出彩。…

约瑟夫问题---C++

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

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

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

Rockchip Android13 Vold(一):Native层

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

代码随想录第38天| 509. 斐波那契数 70. 爬楼梯

理论基础 刷题大纲&#xff1a; 动态规划5步曲&#xff1a; 1、确定dp数组以及下标的含义 2、确定递推公式 3、dp数组如何初始化 4、确定遍历顺序 5、举例推导dp数组 509. 斐波那契数 509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.co…

JAVA 并发编程JUC 锁策略

锁策略 悲观锁乐观锁乐观锁的实现方式公平锁 vs 非公平锁 悲观锁 悲观锁总是假设最坏的情况&#xff0c;认为共享资源每次被访问的时候就会出现问题&#xff0c;例如共享数据被修改等&#xff0c;所以每次在获取资源操作的时候都会上锁&#xff0c;这样其他线程想拿到这个资源…

【03709】24年4月马克思主义基本原理概论考前密卷1

目录 1.选择题 2.简答题 3.论述题(三选二) 1.选择题

文章分享:《二代测序临床报告解读指引》

&#xff3b;摘要&#xff3d; 二代测序&#xff08;next generation sequencing&#xff0c;NGS&#xff09;已成为中国临床肿瘤医生常用检测工具&#xff0c;而中国超 90%临床医生需要 NGS 报告解读支持。因此&#xff0c;为提升临床医生 NGS 报告解读能力&#xff0c;特编写…

【MATLAB源码-第4期】基于MATLAB的1024QAM误码率曲线,以及星座图展示。

1、算法描述 正交幅度调制&#xff08;QAM&#xff0c;Quadrature Amplitude Modulation&#xff09;是一种在两个正交载波上进行幅度调制的调制方式。这两个载波通常是相位差为90度&#xff08;π/2&#xff09;的正弦波&#xff0c;因此被称作正交载波。这种调制方式因此而得…

新天龙八部3永恒经典之江山策仿官方_源码架设教程

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了 一. 效果演示 新天龙…

QAT量化 demo

一、QAT量化基本流程 QAT过程可以分解为以下步骤&#xff1a; 定义模型&#xff1a;定义一个浮点模型&#xff0c;就像常规模型一样。定义量化模型&#xff1a;定义一个与原始模型结构相同但增加了量化操作&#xff08;如torch.quantization.QuantStub()&#xff09;和反量化…

1分钟以上情感短视频素材去哪里找?推荐五个素材网站

在这个充斥着各种短视频的世界里&#xff0c;我就像是一名寻宝的冒险家&#xff0c;不断在素材的海洋中潜水&#xff0c;寻找那些能让我的视频金光闪闪的珍珠。让我告诉你&#xff0c;这不仅仅是一场寻宝&#xff0c;这简直是一场奇妙的冒险。九才素材网&#xff1a; 我的创作…

LeetCode题练习与总结:不同路径Ⅱ--63

一、题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从…

我企业的业务需要制作企业网站吗?11个支持的理由以及5个反对的理由!

如果你的企业经营得还不错&#xff0c;你可能会找出很多理由&#xff0c;说明为什么一个高效的网站对你来说并不那么重要。确实&#xff0c;你明白企业需要在互联网上有一定的存在感&#xff0c;但你可能并不认为一个高效的网站会对你的特定业务产生太大的影响——尤其是当你已…