C语言实现通讯录(超详细)
1.实现怎样一个通讯录
| 实现一个通讯录 | 联系人信息: |
| 1.可以保存100个人的信息 | 名字 |
| 2.添加联系人 | 年龄 |
| 3.删除指定联系人 | 性别 |
| 4.查找指定联系人 | 电话 |
| 5.修改指定联系人 | 住址 |
| 6.排序联系人 | |
| 7.显示所有联系人信息 |
2.通讯录的实现
2.1创建两个源文件和一个头文件
首先我们创建contact.c和test.c,contact.h,在头文件中包含了程序所需的各种头文件并且实现对各种函数的声明,而源文件test.c用于引用函数,contact.c实现函数。这样做的目的是为了各个文件可以处理各自模块的功能,增强逻辑性和代码的清晰度,使得可读性更高。

2.2搭建构架
1.菜单打印
首先在test.c这个源文件里面把菜单打印出来,直接使用printf函数打印出通讯录的功能即可。
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");
}
2.使用do while
这里相比较之前写的游戏代码进行了改进,因为数字的具体含义不知道,所以使用了枚举常量代替,而枚举常量会进行默认赋值,所以从0开始一一对应就行了,增加了代码的可读性。
enum Option
{EXIT,//0ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
int main()
{int input = 0;Contact con;//通讯录InitContact(&con);//初始化通讯录do{menu();printf("请输入你的选择:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:break;case SEARCH:break;case MODIFY:break;case SHOW:ShowContact(&con);break;case SORT:break;case EXIT:printf("退出通讯录\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}
3.使用结构体保存联系人的信息
接下来在contact.h里面创建结构体来包含人的信息,如果觉得在使用结构体时每次都要写成struct PeoInfom比较复杂,可以在struct前面加上typedef,这样的话使用这个结构体写PeoInfom就行。如果我们在数组里面写上数字的话,就是常量,以后如果发生变化,修改起来不够方便,可以使用#define定义常量。
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#define MAME_MAX 40
#define SEX_MAX 10
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100
//类型的声明
typedef struct PeoInfom
{char name[MAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfom;
4.将通讯录初始化
在contact.h里面创建一个结构体,sz记录的是当前通讯录中存放的人的信息个数,PeoInfom data是用来存放数据。
typedef struct Contact
{PeoInfom data[MAX];//存放数据int sz;//记录的是当前通讯录中存放的人的信息个数
}Contact;
在test.c的主函数里面创建通讯录contact con,这个通讯录里面有一个存放数据的数组,还有个联系人数量,现在这个通讯录没有数据。
Contact con;

结果调试以后发现data和sz都是随机数,所以先对通讯录初始化。结构体传参的时候尽量传址,传值的话如果结构体过大会导致性能下降,在test.c中进行传址。
InitContact(&con);//初始化通讯录
在contact.h中声明函数:
void InitContact(Contact* pc);//初始化通讯录
在contact.c中进行函数的实现,sz直接访问赋0即可。data是一块连续的空间,所以使用memset函数将数据全部变为0,data单独放在sizeof内部表示这个数组,第三个参数直接使用sizeof求出data的大小就行了,单位都是字节。当然使用循环也许,但是memset更加方便快捷。
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
5.添加联系人
首先在case语句中写上添加联系人函数AddContact,然后进行传址。
case ADD:AddContact(&con);break;
在contact.h中声明:
void AddContact(Contact* pc);//增加联系人
在contact.c中实现:
首先判断一下通讯录空间是否满了,使用if判断sz是不是等于MAX。如果没有满,则开始输入信息,先打印提醒信息,在输入,名字放在通讯录里面data数组的下标为pc->sz的位置上,所以是pc->data[pc->sz].name,name是数组名,数组名本身是地址,所以不需要使用&。然后模仿名字这样把各项信息输入进去,最后sz++,再打印提示信息。
void AddContact(Contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满,无法增加\n");return;}//增加信息 printf("请输入名字:");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:");scanf("%s",pc->data[pc->sz].sex);printf("请输入电话:");scanf("%s",pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s",pc->data[pc->sz].addr);pc->sz++;printf("添加联系人成功\n");
}

那么我们输入成功之后是看不见这些信息的,所以需要完成show函数,展示出来。
6.展示通讯录信息
首先在case语句中写上添加联系人函数ShowContact,然后进行传址。
case SHOW:ShowContact(&con);break;
在contact.c中实现:
由于不需要修改数据,使用const限制一下参数。
先使用if判断一下通讯录是否为空,如果不是再打印信息。
首先我们把各项信息的标题打印出来,确定好间隔。然后开始打印信息,通过找到data数组的下标找出相应的结构体,然后使用下标访问操作符找出相对应的信息,打印出来。
void ShowContact(const Contact *pc)
{if(ps->sz == 0){printf("通讯录为空\n");}else{int i = 0;//标题printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");//数据for(i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}}
}

7.删除指定联系人
首先在contact.h声明:
void DelContact(Contact* pc);//删除指定联系人
在test.c中使用:
case DEL:DelContact(&con);break;
在contact.c中实现:
删除联系人先判断一下通讯录是否为空,名字单独创建一个数组,然后输入名字,然后开始在通讯录查找名字。
写一个Findbyname的名字查找函数,参数分别是pc这个通讯录和name,在通讯录里面查找sz次,使用strcmp函数比较,如果等于0,就是找到了这个联系人,则返回下标,否则返回-1.
回到删除函数,如果返回的是-1,则联系人不存在。找到了则将返回的下标作为for函数的i,将i+1这个结构体代替i这个结构体,然后不断的循环。如果判断条件设置为i<pc->sz的话,访问到最后一个结构体就会越界,所以是sz-1,并且for循环走完之后sz--,如果要删除最后一个结构体的时候。则不会访问到最后一个结构体,已经被删除了。
int Findbyname(Contact* pc,char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}void DelContact(Contact* pc)
{char name[NAME_MAX];assert(pc);if (pc->sz == 0){printf("通讯录为空\n");}printf("请输入要删除的联系人:");scanf("%s", name);int ret = Findbyname(pc, name);if (ret == -1){printf("要删除的人不存在\n");return;}else {for (int i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");}
}
8.查找联系人
在test.c中使用:
case SEARCH:SearchContact(&con);break;
在contact.h中声明:
void SearchContact(const Contact* pc);//查找联系人
在contact.c中实现:
这里其实是使用到了Findbyname这个函数和展示函数,需要注意的是要把下标换成ret。
void SearchContact(const Contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入联系人:");scanf("%s", name);int ret = Findbyname(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}else{//标题printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");//数据printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);}
}

9.修改联系人
在contact.h里面声明:
void ModifyContact(Contact* pc);//修改联系人信息
在test.c中使用:
case MODIFY:ModifyContact(&con);break;
在contact.c中实现:
修改函数使用Findbyname函数后直接用添加联系人的方法就可以了,需要注意的是把下标改成ret。
void ModifyContact(Contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入联系人:");scanf("%s", name);int ret = Findbyname(pc, name);if (ret == -1){printf("要修改的人不存在\n");return;}printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改联系人成功\n");
}
10.排序联系人
在test.c中使用:
case SORT:SortContact(&con);break;
在contact.h里面声明:
void SortContact(Contact* pc);//排序联系人
在contact.c中实现:
这里使用一个qsort进行排序即可,比较函数使用strcmp。
int cmp_name(const void* e1, const void* e2)
{return (strcmp(((Contact*)e1)->data->name, ((Contact*)e2)->data->name));
}
//联系人排序
void SortContact(Contact* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);//打印printf("排序完成\n");ShowContact(pc);
}
完整代码:
contact.h:
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#define NAME_MAX 40
#define SEX_MAX 10
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100
//类型的声明
typedef struct PeoInfom
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfom;typedef struct Contact
{PeoInfom data[MAX];//存放数据int sz;//记录的是当前通讯录中存放的人的信息个数
}Contact;void InitContact(Contact* pc);//初始化通讯录void AddContact(Contact* pc);//增加联系人void ShowContact(const Contact* pc);//展示通讯录信息void DelContact(Contact* pc);//删除指定联系人void SearchContact(const Contact* pc);//查找联系人void ModifyContact(Contact* pc);//修改联系人信息void SortContact(Contact* pc);//排序联系人
contact.c:
#include"contact.h"
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(Contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满,无法增加\n");return;}//增加信息 printf("请输入名字:");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:");scanf("%s",pc->data[pc->sz].sex);printf("请输入电话:");scanf("%s",pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s",pc->data[pc->sz].addr);pc->sz++;printf("添加联系人成功\n");
}
void ShowContact(const Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空\n");}else{int i = 0;//标题printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");//数据for (i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}}
}
int Findbyname(Contact* pc,char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}
void DelContact(Contact* pc)
{char name[NAME_MAX];assert(pc);if (pc->sz == 0){printf("通讯录为空\n");}printf("请输入要删除的联系人:");scanf("%s", name);int ret = Findbyname(pc, name);if (ret == -1){printf("要删除的人不存在\n");return;}else {for (int i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");}
}
void SearchContact(const Contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入联系人:");scanf("%s", name);int ret = Findbyname(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}else{//标题printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");//数据printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);}
}
void ModifyContact(Contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入联系人:");scanf("%s", name);int ret = Findbyname(pc, name);if (ret == -1){printf("要修改的人不存在\n");return;}printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改联系人成功\n");
}int cmp_name(const void* e1, const void* e2)
{return (strcmp(((Contact*)e1)->data->name, ((Contact*)e2)->data->name));
}
//联系人排序
void SortContact(Contact* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);//打印printf("排序完成\n");ShowContact(pc);
}
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");printf("**********************************\n");
}
enum Option
{EXIT,//0ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
int main()
{int input = 0;Contact con;//通讯录InitContact(&con);//初始化通讯录do{menu();printf("请输入你的选择:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf("退出通讯录\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}
今天的分享到这里就结束啦!谢谢老铁们的阅读,让我们下期再见。
相关文章:
C语言实现通讯录(超详细)
1.实现怎样一个通讯录 实现一个通讯录联系人信息:1.可以保存100个人的信息名字2.添加联系人年龄3.删除指定联系人性别4.查找指定联系人电话5.修改指定联系人住址6.排序联系人7.显示所有联系人信息 2.通讯录的实现 2.1创建两个源文件和一个头文件 首先我们创建con…...
【Python机器学习】零基础掌握MinCovDet协方差估计
如何更精准地评估资产的风险和收益? 在投资领域,资产的风险和收益评估是至关重要的。传统的协方差矩阵虽然在某种程度上能反映资产间的关联性,但也存在一定的局限性。例如如果样本数量较少,传统的协方差矩阵可能会出现偏差,从而影响投资决策。 假设现在有一个投资组合,…...
2023年【四川省安全员A证】模拟试题及四川省安全员A证作业模拟考试
题库来源:安全生产模拟考试一点通公众号小程序 2023年四川省安全员A证模拟试题为正在备考四川省安全员A证操作证的学员准备的理论考试专题,每个月更新的四川省安全员A证作业模拟考试祝您顺利通过四川省安全员A证考试。 1、【多选题】36V照明适用的场所条…...
Flask项目log的集成
一、引入log 在项目的init.py文件中: import logging from logging.handlers import RotatingFileHandlerfrom flask_wtf.csrf import CSRFProtect from flask import Flask from flask_sqlalchemy import SQLAlchemy from redis import StrictRedis from flask_s…...
Open3D(C++) 最小二乘拟合平面(拉格朗日乘子法)
目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。 一、算法原理 设拟合出的平面方程为: a x + b y + c...
c语言练习93:环形链表的约瑟夫问题
环形链表的约瑟夫问题 环形链表的约瑟夫问题_牛客题霸_牛客网 描述 编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。 下一个人继续从 1 开始报数。 n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是…...
从入门到进阶 之 ElasticSearch 文档、分词器 进阶篇
🌹 以上分享 ElasticSearch 文档、分词器 进阶篇,如有问题请指教写。🌹🌹 如你对技术也感兴趣,欢迎交流。🌹🌹🌹 如有需要,请👍点赞💖收藏&#…...
亚马逊云科技多项新功能与服务,助力各种规模的组织拥抱生成式 AI
从初创企业到大型企业,各种规模的组织都纷纷开始接触生成式 AI 技术。这些企业希望充分利用生成式 AI,将自身在测试版、原型设计以及演示版中的畅想带到现实场景中,实现生产力的大幅提升并大力进行创新。但是,组织要怎样才能在企业…...
网站布局都有哪些?
网站布局是指网页中各元素的布局方式,以下是一些常见的网站布局: 栅格布局:将页面分成一个个小格子,再把内容放到对应的格子中。这种布局有利于提高网页的视觉一致性和用户体验,是网站设计中最常用的布局方式之一。流…...
第17章 MQ(一)
17.1 谈谈你对MQ的理解 难度:★ 重点:★★ 白话解析 MQ也要有一跟主线,先理解它是什么,从三个方面去理解就好了:1、概念;2、核心功能;3、分类。 1、概念:MQ(Message Queue),消息队列,是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队…...
LeetCode算法刷题(python) Day41|09动态规划|理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
目录 动规五部曲LeetCode 509. 斐波那契数LeetCode 70. 爬楼梯LeetCode 746. 使用最小花费爬楼梯 动规五部曲 确定dp数组以及下标的含义确定递归公式dp数组如何初始化确定遍历顺序举例推导dp数组 LeetCode 509. 斐波那契数 力扣题目链接 本题最直观是用递归方法 class Sol…...
Spring(四)
1、Spring6整合JUnit 1、JUnit4 User类: package com.songzhishu.spring.bean;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;/*** BelongsProject: Spring6* BelongsPackage: com.songzhishu.spring.bean*…...
2023-10-8讯飞大模型部署2024秋招后端一面(附详解)
1 mybatis的mapper是什么东西 在MyBatis中,mapper是一个核心概念,它起到了桥梁的作用,连接Java对象和数据库之间的数据。具体来说,mapper可以分为以下两个部分: Mapper XML文件: 这是一个XML文件ÿ…...
如何为 Elasticsearch 创建自定义连接器
了解如何为 Elasticsearch 创建自定义连接器以简化数据摄取过程。 作者:JEDR BLASZYK Elasticsearch 拥有一个摄取工具库,可以从多个来源获取数据。 但是,有时你的数据源可能与 Elastic 现有的提取工具不兼容。 在这种情况下,你可…...
Debian11 安装 OpenJDK8
1. 下载安装包 wget http://snapshot.debian.org/archive/debian-security/20220210T090326Z/pool/updates/main/o/openjdk-8/openjdk-8-jdk_8u322-b06-1~deb9u1_amd64.deb wget http://snapshot.debian.org/archive/debian-security/20220210T090326Z/pool/updates/main/o/op…...
[Machine Learning][Part 6]Cost Function代价函数和梯度正则化
目录 拟合 欠拟合 过拟合 正确的拟合 解决过拟合的方法:正则化 线性回归模型和逻辑回归模型都存在欠拟合和过拟合的情况。 拟合 来自百度的解释: 数据拟合又称曲线拟合,俗称拉曲线,是一种把现有数据透过数学方法来代入一条…...
工业自动化编程与数字图像处理技术
工业自动化编程与数字图像处理技术 编程是计算机领域的基础技能,对于从事软件开发和工程的人来说至关重要。在工业自动化领域,C/C仍然是主流的编程语言,特别是用于工业界面(GUI)编程。工业界面是供车间操作员使用的,使用诸如Hal…...
JY61P.C
/** File Name : JY61P.cDescription : attention © Copyright (c) 2020 STMicroelectronics. All rights reserved.This software component is licensed by ST under Ultimate Liberty licenseSLA0044, the “License”; You may not use this file except in complian…...
Go编程:使用 Colly 库下载Reddit网站的图像
概述 Reddit是一个社交新闻网站,用户可以发布各种主题的内容,包括图片。本文将介绍如何使用Go语言和Colly库编写一个简单的爬虫程序,从Reddit网站上下载指定主题的图片,并保存到本地文件夹中。为了避免被目标网站反爬,…...
高性能日志脱敏组件:已支持 log4j2 和 logback 插件
项目介绍 日志脱敏是常见的安全需求。普通的基于工具类方法的方式,对代码的入侵性太强,编写起来又特别麻烦。 sensitive提供基于注解的方式,并且内置了常见的脱敏方式,便于开发。 同时支持 logback 和 log4j2 等常见的日志脱敏…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
js 设置3秒后执行
如何在JavaScript中延迟3秒执行操作 在JavaScript中,要设置一个操作在指定延迟后(例如3秒)执行,可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法,它接受两个参数: 要执行的函数&…...
