静态通讯录

在这里插入图片描述
今天我们分享一下静态通讯录详细解释和代码,之前分享过的只是通讯录的代码,但是我们没有进行讲解和解释,今天我们一边分享它的代码一边解释原因,让大家可以手撕通讯录。现在开始我们的学习吧。

首先我们应该要有三个文件,一个是来放我们的代码就是拿来测试的,我们叫他为test.c,一个就是我们来声明,比如一些函数或者结构体的声明,我们就应该放到这个里面,还有就是定义,我们函数是个怎么样的,怎么实现的我们也需要一个源文件来实现。

在这里插入图片描述
创建好这三个之后我们需要在我们的test.c里面写上我们的菜单,首先我们通讯录是不是一定要具备增删查改的功能,其实还有可以查找,或者排序的功能,那我们先简单的实现一下菜单。

在这里插入图片描述
我们简单的菜单就这样制成了,接下来我们需要做的就就是用switch函数来实现我们选啥就进入哪一个的操作,比如我们要进入add增加用户,那哦我们输入1就行了

Test.c

#include"Contact.h"
void menu()
{printf("**********************\n");printf("***1.add     2.del ***\n");printf("***3.search  4.modify*\n");printf("***5.show    6.sort **\n");printf("***0.exit           **\n");
}
int main()
{int input = 0;do{menu();printf("请输入你要进行的操作>");scanf("%d", &input);switch (input){case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:break;case 0:printf("退出通讯录\n");break;default:printf("输入错误,请重新选择\n");break;}} while (input);return 0;
}

这样看其实我们的代码的可读性并不是很高,所以我们需要进行修改,大家可以看看我的上一篇文章,写的就是有一个枚举的例子,这里我们如果用的是枚举的话,看起来代码的可读性就高很多了,那我们改一下代码

#include"Contact.h"enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
void menu()
{printf("**********************\n");printf("***1.add     2.del ***\n");printf("***3.search  4.modify*\n");printf("***5.show    6.sort **\n");printf("***0.exit           **\n");
}
int main()
{int input = 0;do{menu();printf("请输入你要进行的操作>");scanf("%d", &input);switch (input){case ADD:break;case DEL:break;case SEARCH:break;case MODIFY:break;case SHOW:break;case SORT:break;case EXIT:printf("退出通讯录\n");break;default:printf("输入错误,请重新选择\n");break;}} while (input);return 0;
}

我们这样看的话是不是可读性就稍微高一点了。
完成上面的代码,我们来思考一下我们的通讯录需要存什么东西,我们是不是拿来存人的,所以我们需要这个人的名字,年龄,性别,电话号码,还有这个人的地址,那我们现在需要做的就是定义一个结构体,结构体我们需要的是把他放入到Contact.h中

在这里插入图片描述

typedef struct PeoInf
{char name[20];int age;char sex[5];char tel[12];char addr[20];
}PeoInf;

有了这个结构体我们还需要一个东西来统计它的个数,比如通讯录里面有几个人,这应该是一个局部变量,所以这里我们要做的就是在写一个结构体来实现

typedef struct PeoInf
{char name[20];int age;char sex[5];char tel[12];char addr[20];
}PeoInf;struct Contact
{PeoInf data[100];int sz;
};

上面的代码固然是好,但是我们还是存在一定的缺陷,缺陷是什么呢,我们结构体的数组好像是定死的,本来静态的通讯录就缺少一点动态,我们还把它定死,那比如我们像存101个人,这样不就是改改很麻烦,所以我们可以这样写

#define N 100
#define NMAE_MAX 20
#define SEX_MAX 5
#define TEL_MAX 12
#define ADDR_MAX 20typedef struct PeoInf
{char name[NMAE_MAX];int age;char sex[SEX_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInf;typedef struct Contact
{PeoInf data[N];int sz;
}Contact;

这样就好很对,那我们现在来初始化一下我们的Conact吧

在这里插入图片描述
我们看到这里也是成功的将我们的数据初始化,那来看看我们的代码吧

void InitContact(Contact* pc)
{assert(pc);memset(pc->data, 0, sizeof(pc->data));pc->sz = 0; }

代码也是很简短,但是我们这里必须得传我们的指针过来,否则就不行了,我们要做的是改变结构体中内容,所以就得传他们的地址过来才行,那我们继续来实现下一个吧,下一个我们实现一下ADD吧

void AddContact(Contact* ps)
{assert(ps);assert(ps->sz <= N);//断言如果通讯录满了就不能加了printf("请输入名字\n");scanf("%s", ps->data[ps->sz].name);printf("请输入年龄\n");scanf("%d", &ps->data[ps->sz].age);printf("请输入性别\n");scanf("%s", ps->data[ps->sz].sex);printf("请输入电话\n");scanf("%s", ps->data[ps->sz].tel);printf("请输入地址\n");scanf("%s", ps->data[ps->sz].addr);ps->sz++;printf("增加成功\n");
}

上面就是我们进行增加通讯录的代码,写完这个我们在加一个printf数据的代码也就是显示(show)

void ShowContact(Contact* ps)
{assert(ps);int i = 0;printf("%-20s%-5s%-5s%-12s%-12s\n", "姓名", "年龄", "性别", "电话", "地址");for (i = 0; i < ps->sz; i++){printf("%-20s%-5d%-5s%-12s%-12s\n",ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tel, ps->data[i].addr);}
}

为了让我们的打印显示起来好看一点,我们这里加了对齐,看起来就比较整齐,小编的代码是右对齐,大家也可以进行左对齐的形式,上面的两个代码其实也没有什么要需要注意的,考察的就是对结构体的了解和怎么使用。我们下面来看我们后面的接口函数吧

下一个接口函数就是我们的删除,删除可不是随机删除人,比如我们先要找到这个人的名字,然后进行删除,在删除之前是不是还要看一下通讯录里面还有没有人,如果没有人的话,我们就不能进行删除了,所以这里我们进行强制断言一下

int FindByName(Contact* ps, char name[])
{assert(ps);int i = 0;for (i = 0; i < ps->sz; i++){if (strcmp(ps->data[i].name, name) == 0)return i;}return -1;
}
void DelContact(Contact* ps)
{assert(ps);assert(ps->sz > 0);char name[NMAE_MAX];printf("请输入要删除的人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("通讯录没有这个人\n");return ;}int i = 0;for (i = ret; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}

上面的FIndByName是我们自己写的一个函数,只能在这个文件中使用,所以我们也可以用static修饰一下,就变成这样了

static int FindByName(Contact* ps, char name[])
{assert(ps);int i = 0;for (i = 0; i < ps->sz; i++){if (strcmp(ps->data[i].name, name) == 0)return i;}return -1;
}
void DelContact(Contact* ps)
{assert(ps);assert(ps->sz > 0);char name[NMAE_MAX];printf("请输入要删除的人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("通讯录没有这个人\n");return ;}int i = 0;for (i = ret; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}

这里调试个人感觉特别麻烦,因为我们每次调试一个接口函数的时候,都要重新输入,这是为什么呢,因为我们的数据是存储在内存中的,程序运行结束的时候,我们的数据是无法进行保存的,只要存储在数据库或者文件中,数据才能进行保存,那现在我们来看一下下个接口函数的实现吧

下面一个接口函数就是查找了,查找很简单,我们就不过多解释,直接来看代码吧

void SearchContact(Contact* ps)
{assert(ps);char name[NMAE_MAX];printf("要查找人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("找不到这个人");return;}printf("%-20s%-5d%-5s%-12s%-12s\n",ps->data[ret].name, ps->data[ret].age, ps->data[ret].sex, ps->data[ret].tel, ps->data[ret].addr);}

下面我们增删查改还有一个改的环节,改的话我们首先是不是要找到这个人,然后对它进行修改就行了。

void ModifyContact(Contact* ps)
{assert(ps);char name[NMAE_MAX];printf("要查找人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("找不到这个人");return;}printf("请输入名字\n");scanf("%s", ps->data[ret].name);printf("请输入年龄\n");scanf("%d", &ps->data[ret].age);printf("请输入性别\n");scanf("%s", ps->data[ret].sex);printf("请输入电话\n");scanf("%s", ps->data[ret].tel);printf("请输入地址\n");scanf("%s", ps->data[ret].addr);printf("修改成功\n");}

最后还剩下一个排序,这里我们就假设是按年龄来进行排序的吧,排序大家还记不记得我们有一个库函数,之前我们用冒泡函数来模拟实现,并且我们也掌握它的用法,那这里我们就直接用库函数qsort来实现吧

int CmpByAge(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}
void SortContact(Contact* ps)
{assert(ps);qsort(ps->data, N, sizeof(ps->data[0]), CmpByAge);
}

这样就可以了

那来看一下我们的完整代码吧

Contact.h

#pragma once#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>#define N 100
#define NMAE_MAX 20
#define SEX_MAX 5
#define TEL_MAX 12
#define ADDR_MAX 20typedef struct PeoInf
{char name[NMAE_MAX];int age;char sex[SEX_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInf;typedef struct Contact
{PeoInf data[N];int sz;
}Contact;//初始化
void InitContact(Contact* pc);void AddContact(Contact* ps);void ShowContact(Contact* ps);void DelContact(Contact* ps);void SearchContact(Contact* ps);void ModifyContact(Contact* ps);void SortContact(Contact* ps);

Contact.c

#define _CRT_SECURE_NO_WARNINGS 1#include"Contact.h"void InitContact(Contact* pc)
{assert(pc);memset(pc->data, 0, sizeof(pc->data));pc->sz = 0; }void AddContact(Contact* ps)
{assert(ps);assert(ps->sz <= N);//断言如果通讯录满了就不能加了printf("请输入名字\n");scanf("%s", ps->data[ps->sz].name);printf("请输入年龄\n");scanf("%d", &ps->data[ps->sz].age);printf("请输入性别\n");scanf("%s", ps->data[ps->sz].sex);printf("请输入电话\n");scanf("%s", ps->data[ps->sz].tel);printf("请输入地址\n");scanf("%s", ps->data[ps->sz].addr);ps->sz++;printf("增加成功\n");
}void ShowContact(Contact* ps)
{assert(ps);int i = 0;printf("%-20s%-5s%-5s%-12s%-12s\n", "姓名", "年龄", "性别", "电话", "地址");for (i = 0; i < ps->sz; i++){printf("%-20s%-5d%-5s%-12s%-12s\n",ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tel, ps->data[i].addr);}
}
int FindByName(Contact* ps, char name[])
{assert(ps);int i = 0;for (i = 0; i < ps->sz; i++){if (strcmp(ps->data[i].name, name) == 0)return i;}return -1;
}
void DelContact(Contact* ps)
{assert(ps);assert(ps->sz > 0);char name[NMAE_MAX];printf("请输入要删除的人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("通讯录没有这个人\n");return;}int i = 0;for (i = ret; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}void SearchContact(Contact* ps)
{assert(ps);char name[NMAE_MAX];printf("要查找人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("找不到这个人");return;}printf("%-20s%-5d%-5s%-12s%-12s\n",ps->data[ret].name, ps->data[ret].age, ps->data[ret].sex, ps->data[ret].tel, ps->data[ret].addr);}void ModifyContact(Contact* ps)
{assert(ps);char name[NMAE_MAX];printf("要查找人的名字>");scanf("%s", name);int ret = FindByName(ps, name);if (ret == -1){printf("找不到这个人");return;}printf("请输入名字\n");scanf("%s", ps->data[ret].name);printf("请输入年龄\n");scanf("%d", &ps->data[ret].age);printf("请输入性别\n");scanf("%s", ps->data[ret].sex);printf("请输入电话\n");scanf("%s", ps->data[ret].tel);printf("请输入地址\n");scanf("%s", ps->data[ret].addr);printf("修改成功\n");}int CmpByAge(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}
void SortContact(Contact* ps)
{assert(ps);qsort(ps->data, N, sizeof(ps->data[0]), CmpByAge);
}

接下来就是我们的测试代码

test.c

#define _CRT_SECURE_NO_WARNINGS 1#include"Contact.h"enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
void menu()
{printf("********************************\n");printf("***1.add     2.del *************\n");printf("***3.search  4.modify***********\n");printf("***5.show    6.sort ************\n");printf("***0.exit           ************\n");
}
int main()
{int input = 0;Contact p;InitContact(&p);do{menu();printf("请输入你要进行的操作>");scanf("%d", &input);switch (input){case ADD:AddContact(&p);break;case DEL:DelContact(&p);break;case SEARCH:SearchContact(&p);break;case MODIFY:ModifyContact(&p);break;case SHOW:ShowContact(&p);break;case SORT:SortContact(&p);break;case EXIT:printf("退出通讯录\n");break;default:printf("输入错误,请重新选择\n");break;}} while (input);return 0;
}

这就是我们今天的分享,我们第一次是只分享了代码,这次我们就把整个过程以讲解的方式讲解出来,谢谢大家,我们下次再见

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

java面试题-jvm基础知识

1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&a…

计算机丢失msvcp140_1.dll的解决办法,丢失msvcp140_1.dll的原因

丢失 msvcp140_1.dll 是一个常见的错误信息&#xff0c;通常会在尝试运行某些程序时出现。msvcp140_1.dll 是一个动态链接库文件&#xff0c;它包含了许多 C标准库函数的实现&#xff0c;这些函数在许多程序中都是必需的。因此&#xff0c;如果丢失了该文件&#xff0c;程序可能…

微软最热门的10款前端开源项目!

本文来盘点微软开源的十大前端项目&#xff0c;这些项目在 Github 上获得了超过 45 万 Star&#xff01; Visual Studio Code Visual Studio Code 是一款由微软开发的开源的代码编辑器。它支持多种编程语言&#xff0c;如C、C、C#、Python、JavaScript 和 TypeScript 等&…

记一次linux下pip安装包时出错及奇怪的解决过程

一、问题说明 如图&#xff0c;在使用pip安装测速工具speedtest-cli时&#xff0c;终端提示“Externally managed environment &#xff08;从外部管理的环境&#xff09;”&#xff0c;导致无法安装该库。 二、问题解决 1 尝试提示的解决方案&#xff0c;改用命令apt inst…

c++获取当前时间的字符串

代码 void getNowTimePrefix(std::string& prefix) {std::time_t nowTime;struct tm* p new tm;std::time(&nowTime);localtime_s(p, &nowTime);int year p->tm_year 1900;int month p->tm_mon 1;int day p->tm_mday;int hour p->tm_hour;int …

机器学习算法基础--逻辑回归

目录 1.数据收集及处理 2.数据提取及可视化 3.逻辑回归训练样本并且测试 4.绘制散点决策边界 逻辑回归的方法已经在数学建模里面讲过了&#xff0c;这里就不多讲了。 本篇我们主要是利用逻辑回归的方法来求解分类问题。 1.数据获取及处理 import pandas as pd from sklearn…

计算机竞赛 深度学习YOLO抽烟行为检测 - python opencv

文章目录 1 前言1 课题背景2 实现效果3 Yolov5算法3.1 简介3.2 相关技术 4 数据集处理及实验5 部分核心代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习YOLO抽烟行为检测 该项目较为新颖&#xff0c;适合作为竞赛课…

《Kubernetes部署篇:Ubuntu20.04基于外部etcd+部署kubernetes1.25.14集群(多主多从)》

一、部署架构图 1、架构图如下所示: 2、部署流程图如下所示: 二、环境信息 1、资源下载基于外部etcd+部署容器版kubernetes1.25.14集群资源合集 2、部署规划主机名K8S版本系统版本内核版本IP地址备注k8s-master-121.25.14Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.12ma…

[Hadoop] start-dfs.sh ssh报错

Permission denied (publickey 决解方案 相关命令 cd ~/.sshssh-keygen -t rsa -p""cat id_rsa.pub >> authorized_keyschmod 0600 authorized_keys 相关链接Hadoop: start-dfs.sh permission denied - Stack Overflow Java HotSpot(TM) Server VM warning…

深度学习-一个简单的深度学习推导

文章目录 前言1.sigmod函数2.sigmoid求导3.损失函数loss4.神经网络1.神经网络结构2.公式表示-正向传播3.梯度计算1.Loss 函数2.梯度1.反向传播第2-3层2.反向传播第1-2层 3.python代码 前言 本章主要推导一个简单的两层神经网络。 其中公式入口【入口】 1.sigmod函数 激活函数…

idea创建springboot项+集成阿里连接池druid

创建项目并集成流程 1&#xff1a;前提准备2&#xff1a;创建springboot项目流程3&#xff1a;集成阿里连接池步骤4&#xff1a;集成swagger方便测试5&#xff1a;书写增删改查进行测试6&#xff1a;项目gitee地址 1&#xff1a;前提准备 准备开发工具&#xff1a;idea java环…

世界前沿技术发展报告2023《世界信息技术发展报告》(三)量子信息技术

&#xff08;三&#xff09;量子信息技术 1. 概述2. 量子计算2.1 阿里巴巴达摩院成功研制两比特量子芯片&#xff0c;单比特操控精度超99.97%2.2 加拿大Xanadu公司开发出可编程光量子计算机2.3 美国英伟达公司为经典-量子混合计算推出开发架构2.4 日本国家自然科学研究所开发出…

9+单细胞+实验验证,探讨单基因对癌细胞转移作用的思路方向

今天给同学们分享一篇单细胞实验的生信文章“Identification of RAC1 in promoting brain metastasis of lung adenocarcinoma using single-cell transcriptome sequencing”&#xff0c;这篇文章于2023年5月18日发表在Cell Death Dis期刊上&#xff0c;影响因子为9。 本研究旨…

国庆中秋特辑(三)使用生成对抗网络(GAN)生成具有节日氛围的画作,深度学习框架 TensorFlow 和 Keras 来实现

要用人工智能技术来庆祝国庆中秋&#xff0c;我们可以使用生成对抗网络&#xff08;GAN&#xff09;生成具有节日氛围的画作。这里将使用深度学习框架 TensorFlow 和 Keras 来实现。 一、生成对抗网络&#xff08;GAN&#xff09; 生成对抗网络&#xff08;GANs&#xff0c;…

硕士应聘大专老师

招聘信息 当地人社局、学校&#xff08;官方&#xff09; 公众号&#xff08;推荐&#xff09;&#xff1a; 辅导员招聘 厦门人才就业信息平台 高校人才网V 公告出完没多久就要考试面试&#xff0c;提前联系当地院校&#xff0c;问是否招人。 校招南方某些学校会直接去招老师。…

古代有没有电子元器件?

手机&#xff0c;电脑&#xff0c;电视等等电子产品&#xff0c;无时无刻充斥在我们的生活中&#xff0c;如果有一天突然没有了这些功能多样的电子产品&#xff0c;估计大部分人都会一时之间难以适应。 这就好比正在上网&#xff0c;结果突然被人断了网&#xff0c;导致无网络连…

【计算机毕业设计】基于SpringBoot+Vue记帐理财系统的设计与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序、安卓等)、简历模板、学习资料、…

【操作系统】线程、多线程

为什么要引入线程&#xff1f; 传统的进程只能串行的执行一系列程序&#xff0c;线程增加并发度。同一个进程分为多个线程。 线程是调度的基本单元&#xff0c;程序执行流的最小单位&#xff0c;基本的CPU执行单元。 进程是资源分配的基本单位。 线程的实现方式 用户级线程 代…

软件测试/测试开发丨利用人工智能ChatGPT自动生成架构图

点此获取更多相关资料 简介 架构图通过图形化的表达方式&#xff0c;用于呈现系统、软件的结构、组件、关系和交互方式。一个明确的架构图可以更好地辅助业务分析、技术架构分析的工作。架构图的设计是一个有难度的任务&#xff0c;设计者必须要对业务、相关技术栈都非常清晰…

LeetCode【174. 地下城游戏】

一片丹心图报国&#xff0c;两行清泪为忠家。——于谦 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康…