数据结构2:基于顺序表的通讯录项目

文章目录

  • 头文件
    • SeqList.h
    • Contact.h
  • 实现文件
    • SeqList.c
    • Contact.c
  • 测试文件
    • text.c

头文件

SeqList.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"#define INIT_CAPACITY 4//将顺序表数据类型调整为联系人信息
typedef PersonInfo SLDataType;
//typedef int SLDataType;//动态顺序表 -- 按需申请
typedef struct SeqList {SLDataType* a;int size;int capacity;
}SL;//打印
void SLPrint(SL* ps);//初始化和销毁
void SLInit(SL* ps);
void SLDestory(SL* ps);//扩容
void SLCheckCapacity(SL* ps);//头部插入删除 / 尾部插入删除
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);//查找
void SLInsert(SL* ps, int pos, SLDataType x);//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);

Contact.h

#pragma once#define NAME_MAX 100
#define GENDER_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100//将顺序表重命名为通讯录
typedef struct SeqList Contact;
//这里的struct SeqList是前置声明,声明完之后再进行重命名
//因为这个文件中并没有定义struct SeqList,而又不能包含"SeqList.h"头文件
//因为本文件已经被该头文件包含,所以只能采取前置声明的方式//定义用户数据类型
typedef struct PersonInfo {char name[NAME_MAX];char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}PersonInfo;//通讯录初始化
void ContactInit(Contact* con);//通讯录销毁
void ContactDestory(Contact* con);//添加联系人
void ContactPushBack(Contact* con);//展示通讯录
void ContactPrint(Contact* con);//删除联系人
void ContactDele(Contact* con);//修改联系人
void ContactModify(Contact* con);//查找联系人
void ContactFind(Contact* con);//读取文件
void LoadContact(Contact* con);//保存文件
void SaveContact(Contact* con);

实现文件

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"//需屏蔽,因为数据类型已改变
//打印
//void SLPrint(SL* ps)
//{
//	assert(ps);
//	for (int i = 0; i < ps->size; i++)
//	{
//		printf("%d ", ps->a[i]);
//	}
//	printf("\n");
//}//初始化
void SLInit(SL* ps)
{ps->size = 0;ps->capacity = INIT_CAPACITY;SLDataType* arr = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (arr == NULL) {perror("malloc fail!\n");exit(1);}else {ps->a = arr;arr = NULL;}
}//销毁
void SLDestory(SL* ps)
{assert(ps);//如果顺序表为非空链表,就将ps->a的空间释放if(ps->a)free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}//判断是否需要扩容,如果需要则进行扩容
void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){ps->capacity *= 2;SLDataType* arr = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * (ps->capacity));if (arr == NULL){perror("realloc fail!\n");exit(1);}ps->a = arr;}
}//尾插
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);for (int i = ps->size - 1; i >= 0; i--){ps->a[i + 1] = ps->a[i];}ps->a[0] = x;ps->size++;
}//尾删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);ps->size--;
}//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);for (int i = 0; i < ps->size - 1; i++) {ps->a[i] = ps->a[i + 1];}ps->size--;
}//找到某元素第一次出现的位置
//int SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->a[i] == x)
//			return i;
//	}
//	return -1;
//}//指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos <= ps->size && ps >= 0);SLCheckCapacity(ps);for (int i = ps->size - 1; i >= pos; i--){ps->a[i + 1] = ps->a[i];}ps->a[pos] = x;ps->size++;
}//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos <= ps->size && ps >= 0);for (int i = pos; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

Contact.c

#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"
#include"Contact.h"
#include<string.h>//通讯录初始化
void ContactInit(Contact* con)
{SLInit(con);
}//通讯录销毁
void ContactDestory(Contact* con)
{SLDestory(con);
}//添加联系人
void ContactPushBack(Contact* con)
{//创建联系人结构PersonInfo a;printf("情输入联系人姓名:\n");scanf("%s", &(a.name));printf("情输入联系人性别:\n");scanf("%s", &(a.gender));printf("情输入联系人电话号码:\n");scanf("%s", &(a.tel));printf("情输入联系人地址:\n");scanf("%s", &(a.addr));//尾插SLPushBack(con, a);
}//展示通讯录
void ContactPrint(Contact* con)
{assert(con);if (con->size == 0) {printf("通讯录为空。\n");return;}printf("姓名   性别   电话   地址\n");for (int i = 0; i < con->size; i++){printf("%s ", con->a[i].name);printf("%s ", con->a[i].gender);printf("%s ", con->a[i].tel);printf("%s ", con->a[i].addr);printf("\n");}
}//删除联系人
void ContactDele(Contact* con)
{char name[NAME_MAX] = { 0 };printf("请输入要删除的联系人姓名:");scanf("%s", name);int dele = 0;for (int i = 0; i < con->size; i++){if (strcmp(con->a[i].name, name) == 0){SLErase(con, i);dele = 1;printf("删除成功!\n");break;}}if(dele == 0)printf("联系人信息不存在!\n");
}//修改联系人
void ContactModify(Contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要修改的联系人姓名:");scanf("%s", name);for (int i = 0; i < con->size; i++){if (strcmp(con->a[i].name, name) == 0){printf("情输入新的联系人姓名:\n");scanf("%s", &(con->a[i].name));printf("情输入联系人性别:\n");scanf("%s", &(con->a[i].gender));printf("情输入联系人电话号码:\n");scanf("%s", &(con->a[i].tel));printf("情输入联系人地址:\n");scanf("%s", &(con->a[i].addr));printf("修改成功!\n");return;}}printf("无此联系人信息!\n");
}//查找联系人
void ContactFind(Contact* con)
{assert(con);char name[NAME_MAX];printf("请输入要查找的联系人姓名:");scanf("%s", name);for (int i = 0; i < con->size; i++){if (strcmp(con->a[i].name, name) == 0){printf("姓名   性别   电话   地址\n");printf("%s ", con->a[i].name);printf("%s ", con->a[i].gender);printf("%s ", con->a[i].tel);printf("%s ", con->a[i].addr);printf("\n");return;}}printf("无此联系人信息!\n");return;
}//读取文件
void LoadContact(Contact* con)
{FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("fopen fail!\n");exit(1);}else {PersonInfo tmp;while (fread(&tmp, sizeof(PersonInfo), 1, pf)){SLPushBack(con, tmp);}}fclose(pf);pf = NULL;printf("读取成功!\n");
}//保存文件
void SaveContact(Contact* con)
{FILE* pf = fopen("contact.txt", "wb");if (pf == NULL){perror("fopen fail!\n");exit(1);}else {for (int i = 0; i < con->size; i++){fwrite(&(con->a[i]), sizeof(PersonInfo), 1, pf);}}fclose(pf);pf = NULL;printf("保存成功!\n");return;
}

测试文件

text.c

#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"
#include"Contact.h"void menu()
{printf("*************************************************\n");printf("*************1.增加联系人  2.删除联系人**********\n");printf("*************3.修改联系人  4.查找联系人**********\n");printf("*************5.打印通讯录  0.退出****************\n");printf("*************************************************\n");printf("请选择要进行的操作:\n");
}//测试通讯录
void Test2(Contact* con)
{int input = 0;do {menu();scanf("%d", &input);switch (input){case 1:ContactPushBack(con);break;case 2:ContactDele(con);break;case 3:ContactModify(con);break;case 4:ContactFind(con);break;case 5:ContactPrint(con);default:break;}} while (input);printf("正在退出...\n");
}int main()
{//Test1();Contact a;Contact* con = &a;//初始化ContactInit(con);//读取数据LoadContact(con);Test2(con);//保存数据SaveContact(con);//销毁ContactDestory(con);return 0;
}

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

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

相关文章

基于可变形卷积的大规模视觉基础模型的探索

基于可变形卷积的大规模视觉基础模型的探索 文章目录 基于可变形卷积的大规模视觉基础模型的探索一、简介二、亮点三、项目功能四、模型的应用1、图像模态任务性能2. 图文跨模态任务性能 五、源程序下载 一、简介 本模型包括大规模视觉基础模型"InternImage"&#x…

物联网实战--驱动篇之(五)TEA和AES加密算法

目录 一、前言 二、TEA算法 三、AES算法 四、加解密测试 五、安全性保障 一、前言 物联网的安全性是经常被提及的一个点&#xff0c;如果你的设备之间通讯没有加密的话&#xff0c;那么攻击者很容易就能获取并解析出报文的协议&#xff0c;从而根据攻击者的需要进行设备操…

MongoDB的安装和使用

1.MongoDB 安装 1.1 基于Docker安装 docker run --restartalways -d --name mongo -v /opt/mongodb/data:/data/db -p 27017:27017 mongo:4.0.6 1.2 客户端工具使用 MongoDB Compass | MongoDB 2.MongoDB 使用 2.1 引用依赖包 <dependency><groupId>org.sprin…

信号完整性的常见术语概念(面试常用)

目录 术语 概念一览 1&#xff0e;信号完整性&#xff08;Signal Integrity&#xff09; 2&#xff0e;传输线&#xff08;Transmission Line&#xff09; 3&#xff0e;特性阻抗&#xff08;Characteristic Impedance&#xff09; 4&#xff0e;反射&#xff08;Reflecti…

【环境搭建】ubuntu工作站搭建全流程(显卡4090)

安装ubuntu22.04系统 首先&#xff0c;先压缩windows分区&#xff0c;按住Win X快捷键&#xff0c;选择磁盘管理,压缩分区&#xff0c;压缩出新的分区用于安装ubuntu22.04 windows插入系统盘&#xff0c;点击重启&#xff0c;一直按F12,选择系统盘启动方式语言选择chinese–…

[react优化] 避免组件或数据多次渲染/计算

代码如下 点击视图x➕1,导致视图更新, 视图更细导致a也重新大量计算!!这很浪费时间 function App() {const [x, setX] useState(3)const y x 2console.log(重新渲染, x, y);console.time(timer)let a 0for (let index 0; index < 1000000000; index) {a}console.timeE…

【小红书校招场景题】12306抢票系统

1 坐过高铁吧&#xff0c;有抢过票吗。你说说抢票系统对于后端开发人员而言会有哪些情况&#xff1f; 对于后端开发人员来说&#xff0c;开发和维护一个高铁抢票系统&#xff08;如中国的12306&#xff09;会面临一系列的挑战和情况。这些挑战主要涉及系统的性能、稳定性、数据…

用ansys q3d提取pcb板上的寄生参数及注意事项

需求 画好pcb板后&#xff0c;想要提取回路的寄生参数 1 保存为ad格式 因为之前图方便用立创eda画的板子&#xff0c;结果无法导出成想要的格式。因此需要将立创eda的文件导出为ad格式。立创eda的官网有相关教程。 注意事项&#xff08;只说自己遇到的问题&#xff09; 导…

Ubuntu22.04 + ROS2 Humble的环境配置

Ubuntu22.04 ROS2 Humble的环境配置 文章目录 Ubuntu22.04 ROS2 Humble的环境配置(1) Set locale(2) Setup Sources(3)安装ROS2(4)检查是否成功安装 参考官方网站ROS2-Installation ROS2的各种版本及维护计划&#xff0c;可以参考ROS2-List of Distributions (1) Set locale…

Django中的静态文件、路径、访问静态文件的方法

1.什么是静态文件 不能与服务器端做动态交互的文件都是静态文件 如:图片,css,js,音频,视频,html文件(部分) 2.静态文件配置 在 settings.py 中配置一下两项内容: 1.配置静态文件的访问路径 通过哪个url地址找静态文件 STATIC_URL ‘/static/’ 说…

独一无二:探索单例模式在现代编程中的奥秘与实践

设计模式在软件开发中扮演着至关重要的角色&#xff0c;它们是解决特定问题的经典方法。在众多设计模式中&#xff0c;单例模式因其独特的应用场景和简洁的实现而广受欢迎。本文将从多个角度详细介绍单例模式&#xff0c;帮助你理解它的定义、实现、应用以及潜在的限制。 1. 什…

华为OD-C卷-结队编程[200分]

题目描述 某部门计划通过结队编程来进行项目开发, 已知该部门有 N 名员工,每个员工有独一无二的职级,每三个员工形成一个小组进行结队编程, 结队分组规则如下: 从部门中选出序号分别为 i、j、k 的3名员工,他们的职级分别为 level[i],level[j],level[k], 结队小组满…

FreeRTOS基本介绍

RTOS&#xff0c;Real Time Operating System&#xff0c;实时操作系统&#xff0c;是指具有实时性、能支持实时控制系统工作的操作系统。 它&#xff08;RTOS&#xff09;的首要任务是调动所有资源完成实时控制任务的工作&#xff08;确保实时性&#xff09;&#xff0c;其次才…

数据结构篇1—《顺序表》

文章目录 &#x1f6a9;前言1. 数据结构的概念2. 数据结构的分类3. 顺序表3.1. 顺序表的分类&#xff08;1&#xff09;静态顺序表&#xff08;2&#xff09;动态顺序表 4. 动态顺序表实现4.1. 实现步骤&#xff08;1&#xff09;框架结构&#xff08;2&#xff09;SeqList.h头…

【八股】MySQL

面试题 知道什么是覆盖索引吗&#xff1f; 覆盖索引是指&#xff0c;查询使用的索引&#xff0c;需要返回的列&#xff0c;在该索引的叶子节点中已经能够全部找到。 简单的来说&#xff0c;覆盖索引就是查询索引后&#xff0c;已经得到了所需字段的信息&#xff0c;不需要回表…

如何准备2024年汉字小达人:18道历年考题示例和解析、备考提醒

现在距离2024年第11届汉字小达人比赛还有六个多月的时间&#xff0c;如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。阅读理解不需要。②把历年真题刷刷熟&#x…

linux如何使 CPU使用率保持在指定百分比?

目录 方法1&#xff1a;&#xff08;固定在100%&#xff09; 方法2&#xff1a;&#xff08;可以指定0~100%&#xff09; 方法3&#xff1a;使用ChaosBlade工具&#xff08;0~100%&#xff09; 方法1&#xff1a;&#xff08;固定在100%&#xff09; for i in seq 1 $(cat /pro…

工具01-禅道

禅道使用 禅道介绍禅道核心管理思想-敏捷方法scrum禅道功能 禅道使用 禅道介绍 禅道核心管理思想-敏捷方法scrum 理解&#xff1a;快速迭代&#xff0c;持续交付可以工作的软件项目。 禅道功能 有研发项目管理、内置需求管理、任务管理、测试用例管理、缺陷管理、计划发布等…

vscode常用插件

1. chinese&#xff08;汉化编译器&#xff09; chinese插件适用于 VS Code 的中文&#xff08;简体&#xff09;语言包&#xff0c;此中文&#xff08;简体&#xff09;语言包为 VS Code 提供本地化界面。 2、vetur&#xff08;vue 2开发必备&#xff09;volar&#xff08;vu…

Redis深入解析:HyperLogLog、Bitmap和Geospatial的奇妙应用

本文深入探讨了Redis数据库中的三种特殊数据类型&#xff1a;HyperLogLog、Bitmap和Geospatial。 HyperLogLog用于高效估算集合基数&#xff0c;牺牲小部分准确度以节省空间Bitmap提供位操作&#xff0c;适用于二元数据的高效记录与查询Geospatial处理地理位置数据&#xff0c…