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

C语言进阶——通讯录模拟实现

🌇个人主页:_麦麦_

📚今日名言:只有走在路上,才能摆脱局限,摆脱执着,让所有的选择,探寻,猜测,想象都生机勃勃。——余秋雨《文化苦旅》

目录

一、前言

二、正文

1.大体框架

2.界面显示

3. 创建通讯录

4.初始化通讯录

5.增加联系人

6.显示联系人

7. 删除联系人

 8.查找联系人

9.修改联系人

10. 排序联系人

 三、结语


一、前言

        在上一章的结构体的学习中,相信小伙伴们或多或少都有所收获,但是有的小伙伴可能会问,结构体到底能用来做什么呢?今天,我们就借助结构体和之前所学的知识来实现通讯录。

二、正文

1.大体框架

        相信在座的小伙伴们一定有人做过类似的小游戏或项目,编程的大忌就是将所有的代码都放在同一个文件里,写的时候有多好爽快,后期对代码进行修改和维护的时候就有痛苦。这期通讯录的实现我们大致分为三个模块,一个用于测试通讯录,即对各种函数的调用【text.c】;另一个用于通讯录的实现,其中放置着通讯录功能的具体实现【contact.c】;最后一个就是函数的声明了[contact.h].

2.界面显示

         就像之前的扫雷与三子棋游戏一样,这个通讯录的第一步一定是要让使用者看到通讯录的页面,继而在使用者选择之后进行下一步的操作。因而我们仍旧采取do while 循环,先将页面显示,再根据使用者的输入进行相应的操作。具体实现代码如下:


//通讯录界面显示
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");    //退出通讯录printf("******************************\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");}}while (input);return 0;
}

 

         在以上代码的逻辑下,使用者刚开始就能够看到我们设置好的界面,并进行功能的输入,如果输入为0就退出通讯录,通讯录为功能相应的数字就进行相应的功能【还未填写完整】,若为其他数字,则重新输入。

3. 创建通讯录

        为了实现我们菜单中的各个功能,首先我们要有这些功能的受体——通讯录,只有创建好通讯录 ,才能进行功能的操作。在生活中,我们手机上的通讯录都存有联系人的相关信息,例如姓名,年龄,性别,手机号码等等 ,其次在后面的功能中我们还需要知道这个通讯录中联系人的数量是多少。显然,我们需要一个自定义结构变量来定义通讯录,在这个结构体中有两个变量,一个是存放联系人信息的变量,另一个是存放联系人数量的变量。而存放联系人的信息显然需要一个数组,数组的大小即对应着能存放多少联系人,而数组中的元素就是联系人的信息,这也无法用一个单一类型变量来定义,所以我们还需要额外定义一个结构体变量来代表联系人的各种信息。具体代码如下:

//结构体——联系人的信息
struct peo
{char name[20];    //姓名char sex[10];     //性别int age;          //年龄  char addr[40];    //地址char tel[20];     //电话
};//结构体——通讯录
typedef struct contact
{struct peo Peo[contact_num];	//通讯录中联系人的信息int sz;							//当前存放联系人的个数
}contact;

4.初始化通讯录

        在通讯录的创建之后,就是对其的初始化了,为了方便,我们就都置成0就好了。

//Init_Contact——初始化通讯录void Init_Contact(contact* pc)
{pc->sz = 0;memset(pc, 0, sizeof(pc->Peo));
}

5.增加联系人

         在通讯录的创建和初始化完成之后,就是通讯录功能的实现了。首先是“增加联系人”这一功能。我们先是定义一个函数,这个函数的参数就是我们的通讯录,采用传递通讯录地址的方式,返回值为空,因为我们只是对通讯录的内容进行改变,并不需要返回任何东西。然后是函数的具体实现,我们要做的是在联系人信息这一数组中添加一个联系人,并在添加之后将通讯录当前存储的联系人数量+1。此外如果通讯录已满,我们需要提醒使用者无法再添加联系人。具体代码如下: 

 //Add——增加联系人void Add(contact* Contact){assert(Contact);if (Contact->sz < contact_num){printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[Contact->sz]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[Contact->sz].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[Contact->sz].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[Contact->sz].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[Contact->sz].tel);Contact->sz++;}elseprintf("通讯录已满无法添加\n");}

  

6.显示联系人

        为了观察我们在执行增加联系人这个函数是否成功,我们接下来进行“显示联系人”这一功能的实现。同样的先是定义显示联系人这一函数,函数参数是通讯录,采取传址调用的方式,无需返回任何参数。函数的实现就是依据通讯录中所存储的联系人数量,来调用存储联系人信息的数组,并将其显示在屏幕上,为了数据显示的整齐和美观,笔者对打印的数据类型进行了小小的改善,对数据所占空间进行了设置,并将数据左对齐并在数据后输出一个水平制表符。 

 //Show——展示联系人void Show( const contact* Contact){assert(Contact);int pos = 0;    //联系人对应下标printf("%-20s\t%-10s\t%-4s\t%-40s\t%-20s\n","姓名", "性别", "年龄", "地址", "电话");for (pos = 0; pos < Contact->sz; pos++){printf("%-20s\t%-10s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);}}

7. 删除联系人

        首先是“删除联系人”这一函数的定义,参数为通讯录这一结构体,采取传址调用的方式,返回参数无。继而是函数具体的实现,笔者是根据使用者所输入的所要删除联系人的姓名来找到联系人在数组中对应的下标,从而进行各项信息的删除。这里有个小技巧,无论是删除联系人,修改联系人,搜索联系人都需要在根据输入的姓名对联系人进行查找,因而我们可以将这个功能封装成一个函数,在使用这一功能的时候只需要调用就行了。具体代码实现如下:

//Find_by_name——通过姓名,找到联系人所对应的下标int Find_by_name( const contact* Contact, char *name){int i = 0;for (i = 0; i < Contact->sz; i++){if (strcmp(&(Contact->Peo[i].name),name)==0)return i;}return -1;}//Del——删除联系人void Del(contact* Contact){char name[20] = { 0 };int i = 0;printf("请输入要删除的联系人:>");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{for (i = pos; i < Contact->sz-1; i++){Contact->Peo[i] = Contact->Peo[i + 1];}Contact->sz--;}}

 

 8.查找联系人

        首先是对“查找联系人”函数的定义,函数参数为通讯录,采取传址调用的方式,返回参数为0。然后是具体功能的实现,先是根据输入的姓名查找到对应的下标,再将其显示在屏幕上。具体代码如下:

//Search——搜索联系人void Search(const contact* Contact){char name[20] = {0};printf("请输入要寻找的联系人:>");scanf("%s", name);int pos= Find_by_name(Contact, &name);if (-1==pos){printf("该联系人不存在\n");return;}else{printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性别", "年龄", "地址", "电话");printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);} }

9.修改联系人

         首先是对“修改联系人”函数的定义,函数参数为通讯录,采取传址调用的方式,返回参数为0。然后是具体功能的实现,先是根据输入的姓名查找到对应的下标,再依据添加联系人的代码实现联系人信息的修改。具体代码如下:

//Modify——修改联系人void Modify(contact* Contact){assert(Contact);char name[20] = { 0 };printf("请输入要修改的联系人\n");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[pos]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[pos].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[pos].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[pos].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[pos].tel);}}

10. 排序联系人

        对联系人排序依据有很多,这里仅对联系人的年龄进行排序。采取冒泡排序的方式,冒泡排序的实现在前面的推文已经介绍过了,有兴趣的小伙伴可以康一康。https://blog.csdn.net/m0_73953114/article/details/128766018

//sort——按照年龄对联系人进行排序void sort(contact* Contact,contact* tmp){//执行冒泡排序的趟数int i = 0;for (i = 0; i < Contact->sz - 1; i++){//一趟冒泡排序中交换的次数int j = 0;for (j = 0; j < Contact->sz - 1-i; j++){if (Contact->Peo[j].age > Contact->Peo[j + 1].age){tmp->Peo[0] = Contact->Peo[j];Contact->Peo[j] = Contact->Peo[j + 1];Contact->Peo[j + 1] = tmp->Peo[0];}}}}

        到这里,整个通讯录就写完了,整体的代码如下: 

//main.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");printf("******************************\n");
}int main()
{contact	Contact;	//创建通讯录contact tmp;Init_Contact(&Contact);		//初始化通讯录Init_Contact(&tmp);		int input = 0;do{menu();		//打印菜单printf("请选择你所需的功能:");scanf("%d", &input);switch (input){case 1:Add(&Contact);break;case 2:Del(&Contact);break;case 3:Search(&Contact);break;case 4:Modify(&Contact);break;case 5:Show(&Contact);break;case 6:sort(&Contact,&tmp);break;case 0:printf("退出通讯录\n");break;default:printf("输入错误,请重新输入\n");}}while (input);return 0;
}//contact.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#define contact_num 100
#include <stdio.h>
#include <string.h>
#include <assert.h>//结构体——联系人的信息
struct peo
{char name[20];	//姓名char sex[10];	//性别int age;		//年龄char addr[40];	//地址char tel[20];	//电话
};
//结构体——通讯录
typedef struct contact
{struct peo Peo[contact_num];	//通讯录中联系人的信息int sz;							//当前存放联系人的个数
}contact;void Init_Contact(contact* pc);	//初始化通讯录
void Add(contact* Contact);		//添加联系人
void Show(const contact* Contact);	//展示联系人
void Search(const contact* Contact);	//搜索联系人
void Del(contact* Contact);		//删除联系人
void Modify(contact* Contact);	//修改联系人
void sort(contact* Contact,contact* tmp);	//排序联系人——年龄//contact.c
#include "contact.h"//Init_Contact——初始化通讯录void Init_Contact(contact* pc)
{pc->sz = 0;memset(pc, 0, sizeof(pc->Peo));
}//Add——增加联系人void Add(contact* Contact){assert(Contact);if (Contact->sz < contact_num){printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[Contact->sz]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[Contact->sz].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[Contact->sz].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[Contact->sz].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[Contact->sz].tel);Contact->sz++;}elseprintf("通讯录已满无法添加\n");}//Show——展示联系人void Show( const contact* Contact){assert(Contact);int pos = 0;printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n","姓名", "性别", "年龄", "地址", "电话");for (pos = 0; pos < Contact->sz; pos++){printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);}}//Find_by_name——通过姓名,找到联系人所对应的下标int Find_by_name( const contact* Contact, char *name){int i = 0;for (i = 0; i < Contact->sz; i++){if (strcmp(&(Contact->Peo[i].name),name)==0)return i;}return -1;}//Search——搜索联系人void Search(const contact* Contact){char name[20] = {0};printf("请输入要寻找的联系人:>");scanf("%s", name);int pos= Find_by_name(Contact, &name);if (-1==pos){printf("该联系人不存在\n");return;}else{printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性别", "年龄", "地址", "电话");printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);} }//Del——删除联系人void Del(contact* Contact){char name[20] = { 0 };int i = 0;printf("请输入要删除的联系人:>");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{for (i = pos; i < Contact->sz-1; i++){Contact->Peo[i] = Contact->Peo[i + 1];}Contact->sz--;}}//Modify——修改联系人void Modify(contact* Contact){assert(Contact);char name[20] = { 0 };printf("请输入要修改的联系人\n");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[pos]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[pos].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[pos].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[pos].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[pos].tel);}}//sort——按照年龄对联系人进行排序void sort(contact* Contact,contact* tmp){//执行冒泡排序的趟数int i = 0;for (i = 0; i < Contact->sz - 1; i++){//一趟冒泡排序中交换的次数int j = 0;for (j = 0; j < Contact->sz - 1-i; j++){if (Contact->Peo[j].age > Contact->Peo[j + 1].age){tmp->Peo[0] = Contact->Peo[j];Contact->Peo[j] = Contact->Peo[j + 1];Contact->Peo[j + 1] = tmp->Peo[0];}}}}

 三、结语

        关于通讯录的讲解就已经全部结束了,下期我们会分享自定义类型的其他成员!

        关注我 _麦麦_分享更多干货:_麦麦_的博客_CSDN博客-领域博主
        大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下期见!

相关文章:

C语言进阶——通讯录模拟实现

&#x1f307;个人主页&#xff1a;_麦麦_ &#x1f4da;今日名言&#xff1a;只有走在路上&#xff0c;才能摆脱局限&#xff0c;摆脱执着&#xff0c;让所有的选择&#xff0c;探寻&#xff0c;猜测&#xff0c;想象都生机勃勃。——余秋雨《文化苦旅》 目录 一、前言 二、正…...

【C#基础】C# 变量和常量的使用

序号系列文章1【C#基础】C# 程序通用结构总结2【C#基础】C# 程序基础语法解析3【C#基础】C# 数据类型总结文章目录前言一. 变量&#xff08;variable&#xff09;1&#xff0c;变量定义及初始化2&#xff0c;变量的类别3&#xff0c;接收输出变量二. 常量&#xff08;constant&…...

nvm安装后出现‘node‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

出现这个问题多半是path地址不对。 打开系统环境变量。看看path里面有没有&#xff1f;没有的话&#xff0c;加上就行&#xff01; 我的报错原因就是因为path里没有自动加上nvm的相关路径。 注意项&#xff1a; 1&#xff0c;在安装nvm之前&#xff0c;提前要把本机以前安装…...

张驰咨询:关于六西格玛,有一些常见的疑惑!

​ 很多想要学习六西格玛的学员&#xff0c;经常会有这些困惑&#xff1a; 以前没有接触过六西格玛&#xff0c;需要什么基础吗&#xff1f;自学还是培训&#xff1f;哪些行业会用到六西格玛呢&#xff1f;学习六西格玛对以后的工作有哪些帮助&#xff1f;如何选择六西格玛培…...

【Vercel】教你部署imsyy/home个人主页

本篇博客教你如何部署一个自己的个人主页 项目地址&#xff1a;https://github.com/imsyy/home 本文首发于 慕雪的寒舍 1.fork仓库vercel部署 首先我们点击fork&#xff0c;将仓库复刻到自己的账户 随后进入vercel&#xff0c;点击dashboard-add new-project 选择你复刻的仓库…...

GeekChallenge

2.GeekChallenge 1.web 1.朋友的学妹 url&#xff1a;http://49.234.224.119:7413/ 右键点击查看源码&#xff0c;找到flagU1lDe0YxQF80c19oNExwZnVsbGxsbGx9 然后base64解码得到SYC{F1_4s_h4Lpfullllll} 2.EZwww url&#xff1a;http://47.100.46.169:3901/ 根据网站提示…...

Java文件IO

文章目录Java中的文件操作File常用构造方法方法文件内容的读写——数据流InputStreamFileInputStream利用Scanner进行字符读取OutputStreamPrintWriter按字符读取文件(FileReader)练习代码实例如何按字节进行数据读如何按字节进行数据写如何按字符进行数据读如何按字符进行数据…...

useSSL使用安全套接字协议(史上最全最详细)

useSSL使用安全套接字协议&#xff08;史上最全最详细&#xff09; SSL即为&#xff1a;Secure Sockets Layer 安全套接字协议。 useSSLfalse和useSSLtrue的区别&#xff1a; 在MySQL进行连接时&#xff1a; 如果MySQL的版本是5.7之后的版本必须要加上useSSLfalse&#xff0c…...

面向对象复习(2)

面向对象(2) 对象与引用 java语言中除基本类型之外的变量都称之为引用类型 java中的对象时通过引用对其操作的 Car bm new Car(); 右边的new Car是以Car类为模板,调用无参构造函数,在堆空间中创建一个Car对象 左边的Car bm 在栈中创建了一个Car类型的引用变量,所谓Car的…...

python中使用numpy包的向量矩阵相乘

一直对np的线性运算不太清晰&#xff0c;正好上课讲到了&#xff0c;做一个笔记整个理解一下 1.向量和矩阵 在numpy中&#xff0c;一重方括号表示的是向量vector&#xff0c;vector没有行列的概念。二重方括号表示矩阵matrix&#xff0c;有行列。 代码显示如下&#xff1a; …...

ElasticSearch 学习(一)

目录一、Elasticsearch 简介二、Elasticsearch 发展史三、Elasticsearch 功能四、Elasticsearch 特点五、Elasticsearch 应用场景一、Elasticsearch 简介 Elasticsearch 是一个实时的分布式搜索分析引擎&#xff0c;它能让你以前所未有的速度和规模&#xff0c;去探索你的数据…...

【新】华为OD机试 - 交换字符(Python)| 刷完获取OD招聘渠道

交换字符 题目 给定一个字符串 S 变化规则: 交换字符串中任意两个不同位置的字符 M S 都是小写字符组成 1 <= S.length <= 1000 输入 一串小写字母组成的字符串 输出 按照要求变换得到最小字符串 示例一 输入 abcdef输出 abcdef示例二 输入 bcdefa输出 acde…...

手把手教你解决传说中的NPE空指针异常

1. 前言最近有好几个初学java的小伙伴&#xff0c;甚至是学习到了JavaWeb、框架阶段的小伙伴也跑来问壹哥&#xff0c;该如何解决Java中的NullPointerException空指针异常。因为NPE是初学者特别常见的典型异常&#xff0c;所以壹哥在这里专门写一篇文章&#xff0c;来手把手地教…...

【pytorch安装】conda安装pytorch无法安装cpu版本(完整解决过程)

问题描述 在安装pytorch过程中&#xff0c;发现最后验证torch时总是返回结果为False&#xff0c;结果翻上去发现自己安装的是cpu版本的。 然后又通过conda去更换不同版本尝试&#xff0c;发现都是cpu版本的。 问题分析 通过conda安装pytorch是从源中搜索匹配指令中的文件&am…...

云计算ACP云服务器ECS实例题库

&#x1f618;作者简介&#xff1a;一名99年软件运维应届毕业生&#xff0c;正在自学云计算课程。&#x1f44a;宣言&#xff1a;人生就是B&#xff08;birth&#xff09;和D&#xff08;death&#xff09;之间的C&#xff08;choise&#xff09;&#xff0c;做好每一个选择。&…...

面试题:作用域、变量提升、块级作用域、函数作用域、暂存性死区、var和let的区别

<script>var a 10;(function () {console.log(a)a 5console.log(window.a)var a 20;console.log(a)})() </script> 上述代码&#xff1a; 1、主要是涉及到变量提升和函数作用域&#xff0c;var a20这行代码会在函数作用域中提升var a 至最顶部&#xf…...

JAVA练习49-爬楼梯

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、题目-爬楼梯 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 2月13日练习内容…...

深兰科技机器人商丘制造基地正式投产,助力商丘经济高质量发展

2月9日&#xff0c;深兰科技机器人商丘制造基地投产仪式在商丘市梁园区北航创新园隆重举行。商丘市人大常委会副主任、梁园区委书记张兵&#xff0c;梁园区区长薛天江、河南省装备制造业协会会长张桦&#xff0c;河南省机器人行业协会会长王济昌&#xff0c;深兰科技集团董事长…...

ES倒排索引/查询、写入流程

ES学习笔记 Elasticsearch学习笔记_巨輪的博客-CSDN博客 Elasticsearch学习之图解Elasticsearch中的_source、_all、store和index属性_BUse的博客-CSDN博客 倒排索引 倒排索引&#xff1a;ES倒排索引底层原理及FST算法的实现过程_es fst_Elastic开源社区的博客-CSDN博客 【…...

2023软考考哪个证书好?

软考有三个级别&#xff08;初级&#xff0c;中级和高级&#xff09;&#xff0c;这三个级别分别对应5个方向&#xff0c;下面这张图片呢&#xff0c;可以一目了然&#xff0c;一些小小建议&#xff01;&#xff01;&#xff01;遵循一个原则&#xff1a;首先选专业对口的科目&…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...