当前位置: 首页 > news >正文

数据结构-- 基于顺序表的通讯录代码讲解

       我们了解顺序表之后来一个比较简单的小项目来巩固一下.

        每一个函数我都进行了详细的补充, 各位可以仔细阅读。我将整个项目分为了Contact.h 、Contact.c和test.c三个文件中,其中Contact.h用于函数声明和结构体创建,Contact.c用于函数的实现,test.c用于测试代码。

Contact.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>#define  NAME_MAX  20
#define  GENDER_MAX  10
#define  TELE_MAX  20
#define  ADDR_MAX  100//定义通讯录结构体
typedef struct peopleInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];
}peoInfo;
//改名为通讯录
typedef peoInfo Contact;//改名便于整体替换类型
typedef peoInfo sqDataType;
//定义顺序表
struct SeqList
{sqDataType* arr;int size;int capacity;
};
//缩写改名
typedef struct SeqList SQL;/*000000000000000000000000000000000000000000000000000000000000000000000000000000000000*///顺序表初始化
void SQLInit(SQL* ps);//检查容量函数
void check_capacity(SQL* ps);//顺序表尾插函数
void TailInsert(SQL* ps, sqDataType info);//任意位置删除联系人
void SQLDelete(SQL* ps, int pos, sqDataType info);//任意位置修改顺序表元素
void SQLModify(SQL* ps, int find);
/*0000000000000000000000000000000000000000000000000000000000000000000000000000000000*/
//初始化通讯录
void ContactInit(Contact* pcon);//增加联系人
void ContactAdd(Contact* pcon);//查找联系人
int Contactsearch(SQL* ps);//修改联系人
void ContactModify(SQL* ps);//删除联系人
void ContactDel(Contact* pcon);//文件保存联系人
void KeepFile(Contact* pcon);//显示通讯录
void ContactShow(SQL* ps);//销毁通讯录
void ContactDestroy(SQL* ps);

Contact.c

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
//改名联系人信息为通讯录
typedef peoInfo Contact;//顺序表初始化
void SQLInit(SQL* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->size = 0;
}//检查容量函数
void check_capacity(SQL* ps)
{assert(ps);//三目操作符巧妙开辟空间int newcapacity = (ps->capacity == 0) ? 1 : (2 * ps->capacity);//相等的情况if (ps->size == ps->capacity){sqDataType* pa = (sqDataType*)realloc(ps->arr, sizeof(sqDataType) * newcapacity);if (pa == NULL){perror("realloc");return;}ps->arr = pa;printf("扩容成功\n");}
}//顺序表尾插函数
void TailInsert(SQL* ps, sqDataType info)
{assert(ps && &info);//判断是否需要扩容check_capacity(ps);//插入联系人信息ps->arr[ps->size] = info;ps->size++;printf("添加成功\n");
}//任意位置删除顺序表元素
void SQLDelete(SQL* ps, int pos)
{//检验指针有效性和pos的有效性assert(ps && pos >= 0 && pos < ps->size);//pos后的元素全部向前一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];ps->size--;}printf("删除成功\n");
}//任意位置修改顺序表元素
void SQLModify(SQL* ps, int pos)
{//创建临时结构体变量peoInfo info;//输入联系人信息printf("请输入联系人姓名:>");scanf("%s", info.name);printf("请输入联系人性别:>");scanf("%s", info.gender);printf("请输入联系人年龄:>");scanf("%s", &info.age);printf("请输入联系人电话:>");scanf("%s", info.tele);printf("请输入联系人地址:>");scanf("%s", info.addr);//修改元素信息ps->arr[pos] = info;	
}/************************************************************************************************************************/
//初始化通讯录
void ContactInit(Contact* pcon)
{//其实就是初始化顺序表,因为顺序表的底层就是数组;SQLInit(pcon);//扩容check_capacity(pcon);
}//增加联系人
void ContactAdd(Contact* pcon)
{ //断言assert(pcon);//创建临时联系人结构体peoInfo info;//输入联系人信息printf("请输入联系人姓名:>");scanf("%s", info.name);printf("请输入联系人性别:>");scanf("%s", info.gender);printf("请输入联系人年龄:>");scanf("%d", &info.age);printf("请输入联系人电话:>");scanf("%s", info.tele);printf("请输入联系人地址:>");scanf("%s", info.addr);//尾插函数:插入顺序表TailInsert(pcon,info);
}//查找联系人
int Contactsearch(SQL* ps)//在顺序表中查找
{char name[NAME_MAX];printf("请输入联系人姓名:>");scanf("%s", name);//遍历顺序表,查找联系人for (int i = 0; i < ps->size; i++){if (strcmp(ps->arr[i].name, name) == 0){//找到了return i;}}//没找到return -1;
}//修改联系人信息
void ContactModify(SQL* ps)
{//想要修改联系人,前提是要先找到联系人int find = Contactsearch(ps);if (find < 0){printf("未找到该联系人\n");return;}//修改顺序表中的该元素SQLModify(ps,find);
}//删除联系人
void ContactDel(SQL* ps)
{//想要删除联系人,前提是要先找到联系人int find = Contactsearch(ps);if (find < 0){printf("未找到该联系人\n");return;}//删除顺序表的该元素SQLDelete(ps, find);
}//文件保存联系人
void KeepFile(SQL* ps)
{//打开文件FILE* pf = fopen("C:\\编程\\2024\\continue\\ContactProject_4_7\\ContactProject_4_7\\contact.txt", "w");if (pf == NULL){perror("fopen");return;}//读入文件char arr[100000];for (int i = 0; i < ps->size; i++){fprintf(pf, "%s %s %d %s %s\n", ps->arr[i].name, ps->arr[i].gender, ps->arr[i].age, ps->arr[i].tele, ps->arr[i].addr);}//关闭文件fclose(pf);pf = NULL;
}//显示通讯录
void ContactShow(SQL* ps)
{printf("%s    %s    %s    %s                       %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < ps->size; i++){printf("%s    %s    %d    %s                       %s\n", ps->arr[i].name, ps->arr[i].gender, ps->arr[i].age, ps->arr[i].tele, ps->arr[i].addr);}
}//销毁通讯录
void ContactDestroy(SQL* ps)
{if (ps->arr != NULL){free(ps->arr);ps->arr = NULL;}ps->capacity = ps->size = 0;printf("通讯录已销毁\n");
}

test.c

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
//改名为通讯录
typedef peoInfo Contact;void menu()
{printf("**************************------通讯录-----******************************\n");printf("**************          1、Add        2、Delete         *****************\n");printf("**************          3、Search     4、Modify         *****************\n");printf("**************          5、KeepFile   6、Show           *****************\n");printf("**************          7、Destroy    0、Exit           *****************\n");printf("*************************************************************************\n");
}int main()
{//创建结构体便量Contact con;//初始化ContactInit(&con);int input = 0;int ret = 0;do{//菜单函数menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1://增ContactAdd(&con);break;case 2://删ContactDel(&con);break;case 3://查ret = Contactsearch(&con);if (ret < 0){printf("未找到该联系人\n");}else{//显示联系人信息ContactShow(&con);}break;case 4://改ContactModify(&con);break;case 5://文件操作KeepFile(&con);break;case 6://显示通讯录ContactShow(&con);break;case 7://销毁通讯录ContactDestroy(&con);break;case 0://退出printf("退出通讯录\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);return 0;
}

相关文章:

数据结构-- 基于顺序表的通讯录代码讲解

我们了解顺序表之后来一个比较简单的小项目来巩固一下. 每一个函数我都进行了详细的补充, 各位可以仔细阅读。我将整个项目分为了Contact.h 、Contact.c和test.c三个文件中&#xff0c;其中Contact.h用于函数声明和结构体创建&#xff0c;Contact.c用于函数的实现&#xff0c;t…...

qt-C++笔记之QLabel加载图片

qt-C笔记之QLabel加载图片 —— 2024-04-06 夜 code review! 文章目录 qt-C笔记之QLabel加载图片0.文件结构1.方法一&#xff1a;把图片放在项目路径下&#xff0c;在 .pro 文件中使用 DISTFILES添加图片文件1.1.运行1.2.qt_test.pro1.3.main.cpp 2.方法二&#xff1a;不在 .pr…...

Unity中UI系统1——GUI

介绍 工作原理和主要作用 基本控件 a.文本和按钮控件 练习&#xff1a; b.多选框和单选框 练习&#xff1a; 用的是第三种方法 c.输入框和拖动框 练习&#xff1a; 练习二&#xff1a; e.图片绘制和框 练习&#xff1a; 复合控件 a.工具栏和选择网格 练习&#xff1a; b.滚动视…...

GIt 删除某个特定commit

目的 多次commit&#xff0c;想删掉中间的一个/一些commit 操作方法 一句话说明&#xff1a;利用rebase命令的d表示移除commit的功能&#xff0c;来移除特定的commit # 压缩这3次commit,head~3表示从最近1次commit开始&#xff0c;前3个commit git rebase -i head~3rebase…...

Django --静态文件

静态文件 除了由服务器生成的HTML文件外&#xff0c;WEB应用一般需要提供一些其它的必要文件&#xff0c;比如图片文件、JavaScript脚本和CSS样式表等等&#xff0c;用来为用户呈现出一个完整的网页。在Django中&#xff0c;我们将这些文件统称为“静态文件”&#xff0c;因为…...

蓝桥杯第十三届省赛C++B组(未完)

目录 刷题统计 修剪灌木 X进制减法 【前缀和双指针】统计子矩阵 【DP】积木画 【图DFS】扫雷 李白打酒加强版 DFS (通过64%&#xff0c;ACwing 3/11&#xff09;; DFS(AC) DP&#xff08;AC&#xff09; 砍竹子(X) 刷题统计 题目描述 小明决定从下周一开始努力刷题准…...

编程生活day7--明明的随机数、6翻了、吃火锅

明明的随机数 题目描述 明明想在学校中请一些同学一起做一项问卷调查&#xff0c;为了实验的客观性&#xff0c;他先用计算机生成了N个1到1000之间的随机整数&#xff08;N≤100&#xff09;&#xff0c;对于其中重复的数字&#xff0c;只保留一个&#xff0c;把其余相同的数…...

css酷炫边框

边框一 .leftClass {background: #000;/* -webkit-animation: twinkling 1s infinite ease-in-out; 1秒钟的开始结束都慢的无限次动画 */ } .leftClass::before {content: "";width: 104%;height: 102%;border-radius: 8px;background-image: linear-gradient(var(…...

使用 Docker 部署 Photopea 在线 PS 工具

1&#xff09;Photopea 介绍 GitHub&#xff1a;https://github.com/photopea/photopea 官方手册&#xff1a;https://www.photopea.com/learn/ Adobe 出品的「PhotoShop」想必大家都很熟悉啦&#xff0c;但是「PhotoShop」现在对电脑配置要求越来越高&#xff0c;体积越来越大…...

回溯法(一)——全排列 全组合 子集问题

全排列问题 数字序列 [ l , r ] [l,r] [l,r]​区间内元素的全排列问题 extern int ans[],l,r,num;//num&#xff1a;方案数 extern bool flag[]; void dfs(int cl){//cl:current left&#xff0c;即为当前递归轮的首元素if(cl r 1){//数组已越界&#xff0c;本轮递归结束for…...

【Pt】马灯贴图绘制过程 04-玻璃脏迹

目录 效果 步骤 一、透明玻璃 二、烟熏痕迹 三、粗糙 四、浮尘 效果 步骤 一、透明玻璃 1. 打开纹理集设置&#xff0c;着色器链接选择“新的着色器链接” 在着色器设置中可以看到此时名称为“Main shader &#xff08;Copy&#xff09;” 这里修改名称为“玻璃” 在…...

Rust 程序设计语言学习——枚举模式匹配

枚举&#xff08;enumerations&#xff09;&#xff0c;也被称作 enums。match 允许我们将一个值与一系列的模式相比较&#xff0c;并根据相匹配的模式执行相应代码。 1 枚举的定义 假设我们要跨省出行&#xff0c;有多种交通工具供选择。常用的交通工具有飞机、火车、汽车和轮…...

正则表达式(1)

文章目录 专栏导读1、match2、匹配目标3、通用匹配4、常用匹配规则表格 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对大学生…...

nginx + keepalived 搭建教程

1.安装依赖 yum install -y keepalived systemctl start keepalived systemctl enable keepalived 2.配置 a. keepalived.conf配置 global_defs {router_id nginx_server2 # 机器标识(backup节点为nfs_server2) }vrrp_script chk { script "/etc/keepalived/check_po…...

React事件和原生事件的执行顺序

在 React 中&#xff0c;事件处理分为两种类型&#xff1a;React 合成事件&#xff08;Synthetic Event&#xff09;和原生 DOM 事件&#xff08;Native DOM Event&#xff09;。它们的执行顺序略有不同。 React 合成事件 React 合成事件的执行顺序&#xff1a; React 合成事件…...

为什么在计算查询Q和键K的矩阵乘法时需要转置键矩阵K。示例说明q11,k11代表什么。线性变换矩阵 W_q 用于生成查询,W_k 用于生成键怎么获取的。

目录 为什么在计算查询Q和键K的矩阵乘法时需要转置键矩阵K。 示例说明q11,k11代表什么。...

剑指Offer题目笔记27(动态规划单序列问题)

面试题89&#xff1a; 问题&#xff1a; ​ 输入一个数组表示某条街道上的一排房屋内财产的数量。相邻两栋房屋不能同时被盗&#xff0c;问小偷能偷取到的最多财物。 解决方案一&#xff08;带缓存的递归&#xff09;&#xff1a; 解决方案&#xff1a; 由于有报警系统&…...

撸代码时,有哪些习惯一定要坚持?

我从2011年开始做单片机开发&#xff0c;一直保持以下撸代码的习惯。 1.做好代码版本管理 有些人&#xff0c;喜欢一个程序干到底&#xff0c;直到实现全部的产品功能&#xff0c;我以前做51单片机的项目就是这样。 如果功能比较多的产品&#xff0c;我不建议这样做&#xff0…...

【leetcode面试经典150题】17.罗马数字转整数(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…...

前后端开发之——文章分类管理

原文地址&#xff1a;前后端开发之——文章分类管理 - Pleasure的博客 下面是正文内容&#xff1a; 前言 上回书说到 文章管理系统之添加文章分类。就是通过点击“新建文章分类”按钮从而在服务端数据库中增加一个文章分类。 对于文章分类这个对象&#xff0c;增删改查属于配…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...

【工具教程】多个条形码识别用条码内容对图片重命名,批量PDF条形码识别后用条码内容批量改名,使用教程及注意事项

一、条形码识别改名使用教程 打开软件并选择处理模式&#xff1a;打开软件后&#xff0c;根据要处理的文件类型&#xff0c;选择 “图片识别模式” 或 “PDF 识别模式”。如果是处理包含条形码的 PDF 文件&#xff0c;就选择 “PDF 识别模式”&#xff1b;若是处理图片文件&…...

项目进度管理软件是什么?项目进度管理软件有哪些核心功能?

无论是建筑施工、软件开发&#xff0c;还是市场营销活动&#xff0c;项目往往涉及多个团队、大量资源和严格的时间表。如果没有一个系统化的工具来跟踪和管理这些元素&#xff0c;项目很容易陷入混乱&#xff0c;导致进度延误、成本超支&#xff0c;甚至失败。 项目进度管理软…...