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

【结构体版】通讯录

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前是C语言学习者
✈️专栏:项目
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注


前言

结构体知识回顾:【C语言初阶】结构体+【C语言进阶】结构体
这篇博客将带你用结构体相关知识来写一个简单的通讯录

目录

  • 前言
  • 一、通讯录的要求
  • 二、创建文件
  • 三、创建菜单
  • 四、功能选择逻辑实现
  • 五、创建用户信息
  • 六、创建通讯录
  • 七、完善通讯录功能1 --- 增加联系人
  • 八、完善通讯录功能5 --- 显示联系人的信息
  • 九、完善通讯录功能2 --- 删除指定联系人
  • 十、完善通讯录功能3 --- 查找指定联系人
  • 十一、完善通讯录功能4 --- 修改指定联系人的信息
  • 十二、完善通讯录功能6 --- 排序
  • 十三、源码

一、通讯录的要求

  1. 包含人的相关信息:姓名、年龄、性别、地址和电话
  2. 假设通讯录要存放100个人(具体情况自己定)
  3. 功能:
    增加联系人
    删除指定联系人
    查找指定联系人的信息
    修改指定联系人的信息
    显示所有人的信息
    ⑥可以按照联系人的年龄或者按照名字排序(具体情况自己定)

二、创建文件

为了方便管理,我们可以创建多个文件来实现

  1. test.c - 测试通讯录 (源文件)
  2. contact.c - 通讯录的实现 (源文件)
  3. contact.h - 存放函数的声明 (头文件)
    在这里插入图片描述

三、创建菜单

按照我们的要求,其功能有6种,为了后期要选择相对应的功能,因此我们可以创建一个简易的菜单。

为了能使程序变得更简短而清晰,我们可以封装一个函数menu

【代码实现test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "contact.h"void menu()                
{printf("**********************************\n");  //Add - 添加联系人								printf("****   1. Add     2. del      ****\n");  //del - 删除联系人printf("****   3. search  4. modify   ****\n");  //search - 查找指定联系人printf("****   5. show    6. sort     ****\n");  //modify - 修改指定联系人printf("****        0. exit           ****\n");  //show - 展示联系人printf("**********************************\n");  //sort - 对通讯录排序//exit - 退出程序
}
int main()
{do{//创建菜单menu();} while ();return 0;
}

四、功能选择逻辑实现

创建好菜单后,还要能选择菜单上的功能

【代码实现test.c

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include "contact.h"
void menu()                
{printf("**********************************\n");  //Add - 添加联系人printf("****   1. Add     2. del      ****\n");  //del - 删除联系人printf("****   3. search  4. modify   ****\n");  //search - 查找联系人printf("****   5. show    6. sort     ****\n");  //modify - 修改联系人printf("****        0. exit           ****\n");  //show - 展示联系人printf("**********************************\n");  //sort - 排序//exit - 退出程序
}
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;
}

这里的input可以输入任何值,输入1~6,用户则可以选择相对应的功能,但万一用户不小心输入其他值时,我们可以提醒“选择错误,重新选择”,这时switch语句就派上用场了。最后do while循环条件是input,大家想想,假如input为0,0为假,则结束循环,这不就和退出程序相互匹配上了。(功能的实现还未完善)

五、创建用户信息

根据要求,人的信息必须包含姓名、年龄、性别、地址和电话。因为在信息中,有charint不同的类型,因此我们可以创建一个结构体(概念:结构是一些值的集合,这些值可以称为成员变量结构的每个成员可以是不同类型的变量。)
然后我们把类型的定义以及声明放到contact.h

【代码实现contact.h

//用户信息
typedef struct PeoInfo
{char name[20];//名字int age; //年龄char sex[5]//性别char addr[30] //地址char tele[12]; //电话号码
}PeoInfo;

上面的代码还能优化

#define MAX 100     //通讯录人数的最大值
#define NAME_MAX 20 //人名字符串的最大值
#define SEX_MAX 5   //性别字符的最大值
#define ADDR_MAX 30 //地址字符的最大值
#define TELE_MAX 12 //电话字符的最大值//用户的信息
typedef struct PeoInfo
{char name[NAME_MAX];    //名字int age;                //年龄char sex[SEX_MAX];	    //性别char addr[ADDR_MAX];	//地址char tele[TELE_MAX];    //电话
}PeoInfo;

优化的好处是:万一下次要改变数值的大小就方便多了

六、创建通讯录

定义完用户信息后,接下来就要存放100个人的信息,然后还要记录下当前已经存放的人的信息的个数。那该如何创建通讯录呢?一个是结构体类型、一个是int类型,所以我们再封装一个结构体。老样子,类型的声明和定义我们都放在contact.h

contact.h

#define MAX 100 //人的个数最大值
#define NAME_MAX 20//人名字符串的最大值
#define SEX_MAX 5  //性别字符的最大值
#define ADDR_MAX 30 //地址字符的最大值
#define TELE_MAX 12 //电话字符的最大值//人的信息
typedef struct PeoInfo
{char name[NAME_MAX];    //名字int age;                //年龄char sex[SEX_MAX];	    //性别char addr[ADDR_MAX];	//地址char tele[TELE_MAX];    //电话
}PeoInfo;//创建通讯录
typedef struct Contact
{PeoInfo data[MAX]; //存放人的信息int sz;  //表示当前通讯录有多少个人的信息
}Contact;

接下来就是创建通讯录以及它的初始化

【创建通讯录test.c

在这里插入图片描述

【初始化通讯录test.c

可以封装一个函数来帮助我们初始化(&结构体变量的效率更高)

在这里插入图片描述

初始化通讯录函数的声明放到contact.h

在这里插入图片描述

然后前期又创建一个contact.c文件,它的作用就是用来实现通讯录

在这里插入图片描述

2个可能有疑惑的问题

  1. 头文件:
    由于结构体类型的定义在contact.h中,而我们又想在另外一个文件中使用contact.h的内容,就要包含头文件,而又因为这个头文件不是C语言函数库提供的,所以要用双引号
    2.初始化通讯录
    创建完变量就初始化是一个非常好的编程习惯!但有很多人疑问为什么不这样初始化Contact con = {0},其实这样是可以的,但是这种方法太暴力了。为了提高逼格,我们可以封装一个函数来对其初始化。而函数的声明我们还是要放到contact.h

七、完善通讯录功能1 — 增加联系人

首先在test.c封装一个函数

test.c

在这里插入图片描述

对应的函数的声明,我们定义在contact.h

contact.h

在这里插入图片描述

Add函数的实现

contact.c

在这里插入图片描述

八、完善通讯录功能5 — 显示联系人的信息

显示联系人的信息无非就是打印嘛,那就非常简单了,只需要把通讯录内容遍历打印就行。

首先在test.c封装一个show函数

在这里插入图片描述

然后再对其进行函数的声明,声明就在contact.h中。

在这里插入图片描述

最后实现就在contact.c即可

在这里插入图片描述

接下来我们现在来调试,像代码量大的工程一定要学会调试,不然写到后面发现一堆bug,那就非常尴尬了。
因为我们上一步已经把添加联系人(Add函数)写好了,现在利用show来看看代码效果
在这里插入图片描述

九、完善通讯录功能2 — 删除指定联系人

首先现在test.c中封装del函数

在这里插入图片描述

然后在contact.h对其声明

在这里插入图片描述

最后,在contact.c里实现

void del(Contact* pc)
{char name[NAME_MAX];//记录要删除用户的位置,因为我们的删除方法是从后往前覆盖要删除的对象int position = 0; //通讯录可能一位联系人都没有if (pc->sz == 0){printf("您的通讯录没有联系人,无法删除\n");return;}//通讯录有人//1.找到要删除的人printf("请输入您要删除的对象:");scanf("%s", name);//2.查找通讯录是否有这个人(遍历)for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) //=0说明找到了{position = i;break;}}//3.删除(将后面的人覆盖掉要删除的对象)for (int i = position; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

上面的代码其实还可以再优化一下,大家想:后面还要完善查找联系人信息和修改联系人信息的功能,它们有一个共同的步骤都是要先查找有没有对应的联系人,因此我们可以将查找这一步封装成一个函数。


int fine_by_name(Contact* pc,char name[])
{for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) //=0说明找到了{return i;//返回下标}}return -1;
}
void del(Contact* pc)
{char name[NAME_MAX];if (pc->sz == 0){printf("您的通讯录没有用户,无法删除\n");return;}//1.找到要删除的人printf("请输入您要删除的对象:");scanf("%s", name);//2.查找通讯录是否有这个人(查找函数)int res = fine_by_name(pc, name);if (res == -1){printf("您的通讯录没有这个人\n");return;}//3.删除(将后面的人覆盖掉要删除的对象)for (int i = res; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

十、完善通讯录功能3 — 查找指定联系人

test.c封装一个search函数

在这里插入图片描述

然后在contact.h进行函数的声明

在这里插入图片描述

最后在contact.c实现

在这里插入图片描述

十一、完善通讯录功能4 — 修改指定联系人的信息

首先在test.c封装一个modify函数

在这里插入图片描述

然后在contact.h进行声明

在这里插入图片描述

最后再contact.c中实现即可

void modify(Contact* pc)
{char name[NAME_MAX];printf("请输入要修改人的名字:");scanf("%s", name);//1.查找int res = fine_by_name(pc, name);if (-1 == res){printf("您要修改的对象不存在\n");return;}//2.修改(重新输入)printf("请输入名字:");scanf("%s", pc->data[res].name);printf("请输入年龄:");scanf("%d", &(pc->data[res].age));printf("请输入性别:");scanf("%s", pc->data[res].sex);printf("请输入地址:");scanf("%s", pc->data[res].addr);printf("请输入电话号码:");scanf("%s", pc->data[res].tele);printf("修改成功!\n");
}

十二、完善通讯录功能6 — 排序

对于排序大家可以用很多种方式实现,我这里使用的是qsort函数,毕竟是我前几天刚刚学的知识。如果大家也想了解qsort,可以看看我往期的博客 -> 传送门

test.c部分

在这里插入图片描述

contact.h部分

在这里插入图片描述

contact.c部分

在这里插入图片描述

十三、源码

test.c部分

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include "contact.h"
void menu()                
{printf("**********************************\n");  //Add - 添加联系人printf("****   1. Add     2. del      ****\n");  //del - 删除联系人printf("****   3. search  4. modify   ****\n");  //search - 查找联系人printf("****   5. show    6. sort     ****\n");  //modify - 修改联系人printf("****        0. exit           ****\n");  //show - 展示联系人printf("**********************************\n");  //sort - 排序//exit - 退出程序
}
int main()
{int input = 0;//创建通讯录Contact con;//初始化通讯录InitContact(&con);//结构体传参do{//创建菜单menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:Add(&con);break;case 2:del(&con);break;case 3:search(&con);break;case 4:modify(&con);break;case 5:show(&con);break;case 6:sort(&con);break;case 0:printf("退出通讯录\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);return 0;
}

contact.h部分

#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 100 //人的个数最大值
#define NAME_MAX 20//人名字符串的最大值
#define SEX_MAX 5  //性别字符的最大值
#define ADDR_MAX 30 //地址字符的最大值
#define TELE_MAX 12 //电话字符的最大值//人的信息
typedef struct PeoInfo
{char name[NAME_MAX];     //名字int age;           //年龄char sex[SEX_MAX];	  //性别char addr[ADDR_MAX];	  //地址char tele[TELE_MAX];    //电话
}PeoInfo;//创建通讯录
typedef struct Contact
{PeoInfo data[MAX]; //存放人的信息int sz;//表示当前通讯录有多少个人的信息
}Contact;//初始化通讯录函数
void InitContact(Contact* pc);//增加联系人
void Add(Contact* pc);
//显示联系人
void show(Contact* pc);
//删除联系人
void del(Contact* pc);
//查找联系人
void search(Contact* pc);
//修改联系人
void modify(Contact* pc);
//排序
void sort(Contact* pc);

contact.c部分

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>#include <stdlib.h>
#include "contact.h"//通讯录的初始化
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data)); //初始化为0
}void Add(Contact* pc)
{if (pc ->sz == MAX) //MAX在头文件定义了,表示通讯录最大人数{printf("添加失败,通讯录空间已满\n");return;}//否则就能增加一个人的信息printf("请输入名字:");scanf("%s", pc->data[pc->sz].name);//name是数组名printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);//sex是数组名printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);//addr是数组名printf("请输入电话号码:");scanf("%s", pc->data[pc->sz].tele);//tele是数组名pc->sz++; //增加一个人对于的sz也要增加
}void show(Contact* pc)
{printf("%s\t%s\t%s\t%s\t%s\n", "名字", "年龄", "性别", "地址", "电话");for (int i = 0; i < pc->sz; i++){printf("%s\t%d\t%s\t%s\t%s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}
}int fine_by_name(Contact* pc,char name[])
{for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) //=0说明找到了{return i;}}return -1;
}
void del(Contact* pc)
{char name[NAME_MAX];if (pc->sz == 0){printf("您的通讯录没有用户,无法删除\n");return;}//通讯录有人删除//1.找到要删除的人printf("请输入您要删除的对象:");scanf("%s", name);//2.查找通讯录是否有这个人//查找函数int res = fine_by_name(pc, name);if (res == -1){printf("您的通讯录没有这个人\n");return;}//3.删除(将后面的人覆盖掉要删除的对象)for (int i = res; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void search(Contact* pc)
{char name[NAME_MAX];printf("请输入要查找人的名字:");scanf("%s", name);//利用上一步的查找函数int res = fine_by_name(pc, name);if (-1 == res){printf("您查找的该用户不存在\n");return;}//找到了就打印printf("%s\t%s\t%s\t%s\t%s\n", "名字", "年龄", "性别", "地址", "电话");printf("%s\t%d\t%s\t%s\t%s\n", pc->data[res].name,pc->data[res].age,pc->data[res].sex,pc->data[res].addr,pc->data[res].tele);
}void modify(Contact* pc)
{char name[NAME_MAX];printf("请输入要修改人的名字:");scanf("%s", name);//1.查找int res = fine_by_name(pc, name);if (-1 == res){printf("您要修改的对象不存在\n");return;}//2.找到(重新输入)printf("请输入名字:");scanf("%s", pc->data[res].name);printf("请输入年龄:");scanf("%d", &(pc->data[res].age));printf("请输入性别:");scanf("%s", pc->data[res].sex);printf("请输入地址:");scanf("%s", pc->data[res].addr);printf("请输入电话号码:");scanf("%s", pc->data[res].tele);printf("修改成功!\n");
}int cmp_name(void* p1, void* p2)
{return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}int cmp_age(void* p1, void* p2)
{return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}
void sort(Contact* pc)
{int input = 0;printf("请选择排序方式(默认从小到大):1(年龄)/2(姓名):");scanf("%d", &input);if (input == 2)qsort(pc, pc->sz, sizeof(PeoInfo), cmp_name);elseqsort(pc, pc->sz, sizeof(PeoInfo), cmp_age);printf("恭喜你排序成功,请在选择show中观察效果\n");
}

相关文章:

【结构体版】通讯录

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;项目 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x…...

Debezium系列之:基于debezium采集数据到kafka,再从kafka将数据流式传输到下游数据库

Debezium系列之:基于debezium采集数据到kafka,再从kafka将数据流式传输到下游数据库 一、需求背景二、准备Debezium集群和相关jar包的详细步骤三、查看插件是否加载成功四、源数据库表结构五、根据源数据库表结构准备目标数据库的表六、基于debezium采集数据到kafka七、查看c…...

【2023】华为OD机试真题Java-题目0217-上班之路

上班之路 题目描述 Jungle生活在美丽的蓝鲸城,大马路都是方方正正,但是每天马路的封闭情况都不一样。 地图由以下元素组成: . — 空地,可以达到;* — 路障,不可达到;S — Jungle的家;T — 公司. 其中我们会限制Jungle拐弯的次数,同时Jungle可以清除给定个数的路障,现在…...

基于spring生态的基础后端开发及渗透测试流程(二)

基于spring生态的基础后端开发及渗透测试流程&#xff08;二&#xff09;安全设备IDS蜜罐安全加固渗透测试信息收集子域名域名注册信息企业信息端口扫描源码泄露路径扫描真实ip探测js扫描设备检测蜜罐识别waf识别社工爆破漏洞扫描系统扫描web扫描应急响应继上次写了一份基于spr…...

Python语言零基础入门教程(二十六)

Python OS 文件/目录方法 Python语言零基础入门教程&#xff08;二十五&#xff09; 51、Python os.stat_float_times() 方法 概述 os.stat_float_times() 方法用于决定stat_result是否以float对象显示时间戳。 语法 stat_float_times()方法语法格式如下&#xff1a; os.s…...

人们最想看到的是:你在坚持什么?

【人们最想看到的是&#xff1a;你在坚持什么】 长远规划才能对抗不确定性 品牌也能够对抗不确定性 想想这么多年东搞搞&#xff0c;西搞搞 最后缺乏正向积累的【厚度】 趣讲大白话&#xff1a;把每滴水尽量接到碗里 人吃的是饭&#xff0c;拉出来的是信息 *********** 人们在频…...

300行代码手写spring初体验v1.0版本

70%猜想30%验证 spring&#xff1a;IOC 、DI、AOP、MVC MVC作为入口 web.xml 内部依赖一个DispathcheServlet这样一个接口 先来说一下springMVC的一些基础知识 整体的一个思路&#xff1a; 在web.xml里面进行了一个核心servlet的一个配置 核心就是这个DispatcherServlet …...

100天精通Python(数据分析篇)——第76天:Pandas数据类型转换函数pd.to_numeric(参数说明+实战案例)

文章目录专栏导读一、to_numeric参数说明0. 介绍1. arg1&#xff09;接收列表2&#xff09;接收一维数组3&#xff09;接收Series对象2. errors1&#xff09;errorscoerce2&#xff09;errors ignore3. downcast1&#xff09;downcastinteger2&#xff09;downcastsigned3&…...

链表(超详细--包教包会)

目录 一、概述 二、对链表的基本操作 三、链表的分类 四、静态链表 五、动态链表 1、malloc函数 2、calloc函数 3、free函数 六、动态链表的建立 七、输出链表中的数据 八、查找节点 九、删除节点 十、插入节点 十一、整体代码 一、概述 链表存储结构是一种动态数据…...

爬虫基本知识的认知(爬虫流程 HTTP构建)| 爬虫理论课,附赠三体案例

爬虫是指通过程序自动化地从互联网上获取数据的过程。 基本的爬虫流程可以概括为以下几个步骤&#xff1a; 发送 HTTP 请求&#xff1a;通过 HTTP 协议向指定的 URL 发送请求&#xff0c;获取对应的 HTML 页面。解析 HTML 页面&#xff1a;使用 HTML 解析器对获取的 HTML 页面…...

Ubuntu20.04如何安装虚拟机(并安装Android)

安装虚拟机&#xff08;KVM&#xff09;这种KVM只能安装windows无法安装安卓(From https://phoenixnap.com/kb/ubuntu-install-kvm)A type 2 hypervisor enables users to run isolated instances of other operating systems inside a host system. As a Linux based OS, Ubun…...

【腾讯一面】我对我的Java基础不自信了

我对我的Java基础不自信了1、List和set的区别&#xff1f;2、HashSet 是如何保证不重复的3、HashMap是线程安全的吗&#xff0c;为什么不是线程安全的&#xff1f;4、HashMap的扩容过程5、Java获取反射的三种方法6、Redis持久化机制原理7、redis持久化的方式各有哪些优缺点1、L…...

前端都在聊什么 - 第 2 期

Hello 小伙伴们早上、中午、下午、晚上、深夜好&#xff0c;我是爱折腾的 jsliang~「前端都在聊什么」是 jsliang 日常写文章/做视频/玩直播过程中&#xff0c;小伙伴们的提问以及我的解疑整理。本期对应 2023 年的 01.16-01.31 这个时间段。本期针对「规划」「工作」「学习」「…...

每天一道大厂SQL题【Day11】微众银行真题实战(一)

每天一道大厂SQL题【Day11】微众银行真题实战(一) 大家好&#xff0c;我是Maynor。相信大家和我一样&#xff0c;都有一个大厂梦&#xff0c;作为一名资深大数据选手&#xff0c;深知SQL重要性&#xff0c;接下来我准备用100天时间&#xff0c;基于大数据岗面试中的经典SQL题&…...

Cosmos 基础教程(一) -- 不可不知的开发术语

CometBFT DOC 您可以在本节中找到几个技术术语的概述&#xff0c;包括每个术语的解释和进一步资源的链接——在使用Cosmos SDK进行开发时&#xff0c;所有这些都是必不可少的。 在本节中&#xff0c;您将了解以下术语: Cosmos and Interchain LCD RPC Protobuf -协议缓冲…...

JAVA JDK 常用工具类和工具方法

目录 Pair与Triple Lists.partition-将一个大集合分成若干 List集合操作的轮子 对象工具Objects 与ObjectUtils 字符串工具 MapUtils Assert断言 switch语句 三目表达式 IOUtils MultiValueMap MultiMap JAVA各个时间类型的转换&#xff08;LocalDate与Date类型&a…...

Spring Bean循环依赖

解决SpringBean循环依赖为什么需要3级缓存&#xff1f;回答&#xff1a;1级Map保存单例bean。2级Map 为了保证产生循环引用问题时&#xff0c;每次查询早期引用对象&#xff0c;都拿到同一个对象。3级Map保存ObjectFactory对象。数据结构1级Map singletonObjects2级Map earlySi…...

Hive 2.3.0 安装部署(mysql 8.0)

Hive安装部署 一.Hive的安装 1、下载apache-hive-2.3.0-bin.tar.gz 可以自行下载其他版本&#xff1a;http://mirror.bit.edu.cn/apache/hive/ 2.3.0版本链接&#xff1a;https://pan.baidu.com/s/18NNVdfOeuQzhnOHVcFpnSw 提取码&#xff1a;xc2u 2、用mobaxterm或者其他连接…...

IPD术语表

简称英文全称中文ABPannual business plan年度商业计划ABCactivity -based costing基于活动的成本估算ABMactivity -based management基于活动的管理ADCPavailability decision check point可获得性决策评审点AFDanticipatory failure determination预防错误决定AMEadvanced ma…...

目标检测损失函数 yolos、DETR为例

yolos和DETR&#xff0c;除了yolos没有卷积层以外&#xff0c;几乎所有操作都一样。 HF官方文档 因为目标检测模型&#xff0c;实际会输出几百几千个“框”&#xff0c;所以损失函数计算比较复杂。损失函数为偶匹配损失 bipartite matching loss&#xff0c;参考此blog targe…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

如何通过git命令查看项目连接的仓库地址?

要通过 Git 命令查看项目连接的仓库地址&#xff0c;您可以使用以下几种方法&#xff1a; 1. 查看所有远程仓库地址 使用 git remote -v 命令&#xff0c;它会显示项目中配置的所有远程仓库及其对应的 URL&#xff1a; git remote -v输出示例&#xff1a; origin https://…...