关于注册登录功能制作的步骤(文件IO存储+LVGL弹窗提示)

按你的需求(文件IO存储+LVGL弹窗提示),工程需创建以下文件,代码按功能模块化存放,清晰明了:

一、需要创建的文件清单
文件名 作用 存放内容 
main.c 程序入口 主函数、硬件初始化、LVGL初始化、启动界面 
ui.h 界面函数声明 声明登录/注册界面创建、页面跳转等函数 
ui.c 界面实现 用LVGL创建登录/注册界面、按钮回调、lv_msgbox弹窗提示 
user_file.h 文件操作函数声明 声明注册写入、登录查找、账号检查等函数 
user_file.c 文件IO逻辑实现 实现用户信息的文件读写(注册时写入、登录时查找比对) 

二、各文件代码及存放位置

1. main.c(工程入口)

存放位置:工程根目录,作为程序启动点
#include "lvgl/lvgl.h"
#include "ui.h"       // 包含界面函数
#include "user_file.h"// 包含文件操作函数// 硬件初始化(GEC6818屏幕、触摸驱动)
static void hardware_init(void) {// 此处添加开发板硬件初始化代码(如LCD初始化、触摸驱动初始化)// 例:打开LCD设备、设置分辨率为800x480等
}int main(void) {// 1. 初始化硬件hardware_init();// 2. 初始化LVGLlv_init();lv_port_disp_init();  // 显示接口初始化(适配GEC6818 LCD)lv_port_indev_init(); // 输入设备初始化(适配触摸)// 3. 启动登录界面create_login_ui();// 4. LVGL主循环while (1) {lv_task_handler();  // 处理LVGL任务usleep(5000);       // 5ms延迟}return 0;
}


2. ui.h(界面函数声明)

存放位置:工程根目录,声明ui.c中的所有函数
#ifndef UI_H
#define UI_H#include "lvgl/lvgl.h"// 登录界面创建
void create_login_ui(void);// 注册界面创建
void create_reg_ui(void);// 登录成功跳转(定时器回调)
void login_success(lv_timer_t *t);// 注册成功返回登录页(定时器回调)
void reg_success_back(lv_timer_t *t);#endif // UI_H


3. ui.c(界面实现+弹窗提示)

存放位置:工程根目录,实现界面和交互逻辑
#include "ui.h"
#include "user_file.h"  // 调用文件操作函数// 输入框缓存(登录界面)
static char login_user[32] = "";
static char login_pwd[32] = "";// 输入框缓存(注册界面)
static char reg_user[32] = "";
static char reg_pwd[32] = "";// 登录界面创建
void create_login_ui(void) {lv_obj_clean(lv_scr_act());  // 清空当前界面// 1. 账号输入区lv_obj_t *user_label = lv_label_create(lv_scr_act());lv_label_set_text(user_label, "账号:");lv_obj_align(user_label, LV_ALIGN_TOP_LEFT, 50, 100);lv_obj_t *user_ta = lv_textarea_create(lv_scr_act());lv_textarea_set_placeholder_text(user_ta, "请输入账号");lv_textarea_set_max_length(user_ta, 31);lv_obj_set_size(user_ta, 200, 50);lv_obj_align_to(user_ta, user_label, LV_ALIGN_OUT_RIGHT_MID, 20, 0);lv_textarea_set_text(user_ta, login_user);// 2. 密码输入区lv_obj_t *pwd_label = lv_label_create(lv_scr_act());lv_label_set_text(pwd_label, "密码:");lv_obj_align(pwd_label, LV_ALIGN_TOP_LEFT, 50, 180);lv_obj_t *pwd_ta = lv_textarea_create(lv_scr_act());lv_textarea_set_placeholder_text(pwd_ta, "请输入密码");lv_textarea_set_password_mode(pwd_ta, true);  // 密码隐藏lv_textarea_set_max_length(pwd_ta, 31);lv_obj_set_size(pwd_ta, 200, 50);lv_obj_align_to(pwd_ta, pwd_label, LV_ALIGN_OUT_RIGHT_MID, 20, 0);lv_textarea_set_text(pwd_ta, login_pwd);// 3. 登录按钮(带回调)lv_obj_t *login_btn = lv_btn_create(lv_scr_act());lv_obj_set_size(login_btn, 100, 40);lv_obj_align(login_btn, LV_ALIGN_TOP_MID, -60, 280);lv_obj_t *login_btn_label = lv_label_create(login_btn);lv_label_set_text(login_btn_label, "登录");lv_obj_add_event_cb(login_btn, login_btn_cb, LV_EVENT_CLICKED, user_ta);  // 传账号输入框// 4. 跳转到注册按钮lv_obj_t *to_reg_btn = lv_btn_create(lv_scr_act());lv_obj_set_size(to_reg_btn, 100, 40);lv_obj_align(to_reg_btn, LV_ALIGN_TOP_MID, 60, 280);lv_obj_t *to_reg_label = lv_label_create(to_reg_btn);lv_label_set_text(to_reg_label, "注册");lv_obj_add_event_cb(to_reg_btn, to_reg_cb, LV_EVENT_CLICKED, NULL);
}// 注册界面创建
void create_reg_ui(void) {lv_obj_clean(lv_scr_act());  // 清空当前界面// 1. 新账号输入区lv_obj_t *reg_user_label = lv_label_create(lv_scr_act());lv_label_set_text(reg_user_label, "新账号:");lv_obj_align(reg_user_label, LV_ALIGN_TOP_LEFT, 50, 100);lv_obj_t *reg_user_ta = lv_textarea_create(lv_scr_act());lv_textarea_set_placeholder_text(reg_user_ta, "请设置账号");lv_textarea_set_max_length(reg_user_ta, 31);lv_obj_set_size(reg_user_ta, 200, 50);lv_obj_align_to(reg_user_ta, reg_user_label, LV_ALIGN_OUT_RIGHT_MID, 20, 0);lv_textarea_set_text(reg_user_ta, reg_user);// 2. 新密码输入区lv_obj_t *reg_pwd_label = lv_label_create(lv_scr_act());lv_label_set_text(reg_pwd_label, "新密码:");lv_obj_align(reg_pwd_label, LV_ALIGN_TOP_LEFT, 50, 180);lv_obj_t *reg_pwd_ta = lv_textarea_create(lv_scr_act());lv_textarea_set_placeholder_text(reg_pwd_ta, "请设置密码");lv_textarea_set_password_mode(reg_pwd_ta, true);lv_textarea_set_max_length(reg_pwd_ta, 31);lv_obj_set_size(reg_pwd_ta, 200, 50);lv_obj_align_to(reg_pwd_ta, reg_pwd_label, LV_ALIGN_OUT_RIGHT_MID, 20, 0);lv_textarea_set_text(reg_pwd_ta, reg_pwd);// 3. 注册按钮(带回调)lv_obj_t *reg_btn = lv_btn_create(lv_scr_act());lv_obj_set_size(reg_btn, 100, 40);lv_obj_align(reg_btn, LV_ALIGN_TOP_MID, -60, 280);lv_obj_t *reg_btn_label = lv_label_create(reg_btn);lv_label_set_text(reg_btn_label, "注册");lv_obj_add_event_cb(reg_btn, reg_btn_cb, LV_EVENT_CLICKED, reg_user_ta);  // 传账号输入框// 4. 返回登录按钮lv_obj_t *back_btn = lv_btn_create(lv_scr_act());lv_obj_set_size(back_btn, 100, 40);lv_obj_align(back_btn, LV_ALIGN_TOP_MID, 60, 280);lv_obj_t *back_label = lv_label_create(back_btn);lv_label_set_text(back_label, "返回");lv_obj_add_event_cb(back_btn, to_login_cb, LV_EVENT_CLICKED, NULL);
}// 登录按钮回调(核心:调用文件查找函数+lv_msgbox提示)
static void login_btn_cb(lv_event_t *e) {lv_obj_t *user_ta = lv_event_get_user_data(e);lv_obj_t *pwd_ta = lv_obj_get_next_sibling(user_ta);  // 密码输入框(账号输入框的下一个兄弟组件)const char *user = lv_textarea_get_text(user_ta);const char *pwd = lv_textarea_get_text(pwd_ta);// 调用登录验证(来自user_file.c)int ret = login_check(user, pwd);lv_obj_t *msg;  // LVGL弹窗// 用lv_msgbox显示结果(静态调用,直接创建)if (ret == 0) {msg = lv_msgbox_create(NULL, "成功", "登录成功!即将进入系统", NULL, false);lv_timer_create(login_success, 1500, NULL);  // 1.5秒后跳转主页面} else if (ret == -1) {msg = lv_msgbox_create(NULL, "提示", "暂无注册用户,请先注册", NULL, false);} else {msg = lv_msgbox_create(NULL, "错误", "账号或密码错误", NULL, false);}lv_obj_center(msg);  // 弹窗居中
}// 注册按钮回调(核心:调用文件写入函数+lv_msgbox提示)
static void reg_btn_cb(lv_event_t *e) {lv_obj_t *reg_user_ta = lv_event_get_user_data(e);lv_obj_t *reg_pwd_ta = lv_obj_get_next_sibling(reg_user_ta);  // 密码输入框const char *user = lv_textarea_get_text(reg_user_ta);const char *pwd = lv_textarea_get_text(reg_pwd_ta);// 调用注册函数(来自user_file.c)int ret = register_save(user, pwd);lv_obj_t *msg;if (ret == 0) {msg = lv_msgbox_create(NULL, "成功", "注册成功!即将返回登录", NULL, false);lv_timer_create(reg_success_back, 1500, NULL);  // 1.5秒后返回登录页} else if (ret == -1) {msg = lv_msgbox_create(NULL, "错误", "账号或密码不能为空", NULL, false);} else if (ret == -2) {msg = lv_msgbox_create(NULL, "错误", "账号已存在", NULL, false);} else {msg = lv_msgbox_create(NULL, "错误", "注册失败(文件写入错误)", NULL, false);}lv_obj_center(msg);
}// 辅助回调:跳转到注册界面
static void to_reg_cb(lv_event_t *e) {create_reg_ui();
}// 辅助回调:返回登录界面
static void to_login_cb(lv_event_t *e) {create_login_ui();
}// 登录成功后跳转主页面
void login_success(lv_timer_t *t) {lv_obj_clean(lv_scr_act());lv_obj_t *main_label = lv_label_create(lv_scr_act());lv_label_set_text(main_label, "欢迎进入系统!");lv_obj_center(main_label);
}// 注册成功后返回登录页
void reg_success_back(lv_timer_t *t) {create_login_ui();
}


4. user_file.h(文件操作声明)

存放位置:工程根目录,声明user_file.c中的函数
#ifndef USER_FILE_H
#define USER_FILE_H#include <stdio.h>// 注册:将账号密码写入文件(返回0成功,-1空输入,-2账号已存在,-3文件错误)
int register_save(const char *username, const char *password);// 登录:从文件查找匹配(返回0成功,-1无注册用户,-2账号密码错误)
int login_check(const char *username, const char *password);#endif // USER_FILE_H


5. user_file.c(文件IO实现)

存放位置:工程根目录,实现注册写入和登录查找逻辑
#include "user_file.h"
#include <string.h>

// 存储用户信息的文本文件(程序运行时自动创建)
#define USER_FILE "users.txt"

// 内部函数:检查账号是否已存在
static int user_exist(const char *username) {
FILE *fp = fopen(USER_FILE, "r");
if (!fp) return 0;  // 文件不存在,无重复账号    char line[128], tmp_user[32];
while (fgets(line, sizeof(line), fp)) {
// 按"账号:密码"格式解析一行
if (sscanf(line, "%31[^:]", tmp_user) == 1) {  // %31[^:] 匹配到":"前的字符串(账号)
if (strcmp(tmp_user, username) == 0) {
fclose(fp);
return

1;  // 账号已存在}}}fclose(fp);return 0;  // 账号不存在
}// 注册:写入文件(对外接口)
int register_save(const char *username, const char *password) {// 检查输入合法性if (strlen(username) == 0 || strlen(password) == 0) {return -1;  // 账号或密码为空}if (user_exist(username)) {return -2;  // 账号已存在}// 追加写入文件("a"模式:不存在则创建,存在则追加)FILE *fp = fopen(USER_FILE, "a");if (!fp) return -3;  // 文件打开失败// 按"账号:密码"格式写入(方便后续解析)fprintf(fp, "%s:%s\n", username, password);fclose(fp);return 0;  // 注册成功
}// 登录:查找匹配(对外接口)
int login_check(const char *username, const char *password) {FILE *fp = fopen(USER_FILE, "r");if (!fp) return -1;  // 文件不存在(无注册用户)char line[128], tmp_user[32], tmp_pwd[32];while (fgets(line, sizeof(line), fp)) {// 解析一行中的账号和密码(格式:账号:密码)if (sscanf(line, "%31[^:]:%31s", tmp_user, tmp_pwd) == 2) {// 比对账号和密码if (strcmp(tmp_user, username) == 0 && strcmp(tmp_pwd, password) == 0) {fclose(fp);return 0;  // 匹配成功}}}fclose(fp);return -2;  // 未找到匹配(账号或密码错误)
}


三、工程文件结构
project/                  # 工程根目录
├── main.c                # 主程序入口
├── ui.h                  # 界面函数声明
├── ui.c                  # 登录/注册界面+弹窗实现
├── user_file.h           # 文件操作函数声明
├── user_file.c           # 注册写入/登录查找的文件IO逻辑
└── Makefile              # 编译配置(之前提供的适配arm-linux-gcc版本)
四、关键说明

1. 自动生成的文件:
程序运行时会在当前目录自动创建 users.txt(存储注册信息,格式为账号:密码),无需手动创建。

抱歉,之前的内容确实没写完,补充完整关键说明部分:

四、关键说明(补充完整)

2. 代码关联:

◦ ui.c 调用 user_file.c 中的 register_save 和 login_check 实现数据存储与验证,两者通过 user_file.h 声明接口关联。

◦ 所有界面跳转和弹窗提示都在 ui.c 中通过LVGL组件实现,其中 lv_msgbox 是核心弹窗组件,通过 lv_msgbox_create 静态创建,无需提前初始化,直接调用即可显示提示信息(如登录结果、注册状态)。

3. 输入框数据处理:

◦ 登录和注册界面的输入框使用 lv_textarea 组件,输入内容通过 lv_textarea_get_text 获取,存储在静态字符数组(如 login_user、reg_pwd)中,确保数据在界面切换时不丢失。

4. 界面切换逻辑:

◦ 每次切换界面(如从登录页到注册页)前,用 lv_obj_clean(lv_scr_act()) 清空当前屏幕,避免组件叠加。

◦ 按钮回调函数(如 to_reg_cb、to_login_cb)直接调用新界面的创建函数(create_reg_ui、create_login_ui)实现跳转。

5. 定时器使用:

◦ 弹窗显示后,通过 lv_timer_create 设定延迟(1.5秒),到期后执行跳转逻辑(如登录成功后进入主页面、注册成功后返回登录页),提升用户体验。

五、可能遇到的问题及解决

• LVGL库链接错误:确保 Makefile 中 LVGL_DIR 路径正确,且LVGL已针对GEC6818交叉编译(生成 liblvgl.a)。

• 界面错位:根据开发板实际分辨率(如480x272)调整 lv_obj_align 中的坐标参数(如 50, 100 等)。

• 文件读写失败:检查开发板文件系统权限,确保程序运行目录可读写(一般 /tmp 或用户目录权限足够)。

按以上内容,工程可完整实现“注册-登录-数据存储-弹窗提示”的全流程,直接编译运行即可。


以下是两种编译方法的详细说明,包含适配的Makefile和直接使用arm-linux-gcc命令的完整指令,可直接用于生成目标文件:

一、使用 Makefile 编译(推荐)

创建 Makefile 后,只需执行 make 即可自动编译,适合多次修改和构建。1. Makefile 内容(适配 arm-linux-gcc)

# 交叉编译工具链
CC = arm-linux-gcc# LVGL库路径(替换为你的LVGL实际路径,如/opt/lvgl)
LVGL_DIR = /path/to/your/lvgl# 源文件列表(工程所有.c文件)
SRCS = main.c ui.c user_file.c# 目标文件(自动生成)
OBJS = $(SRCS:.c=.o)# 生成的可执行文件名
TARGET = login_demo# 编译选项(包含头文件路径和架构参数)
CFLAGS = -I. \-I$(LVGL_DIR) \-I$(LVGL_DIR)/src \-I$(LVGL_DIR)/src/core \-I$(LVGL_DIR)/src/hal \-I$(LVGL_DIR)/src/widgets \-O2 -Wall -Wextra \-mlittle-endian \-marm \-mcpu=arm926ej-s  # 若GEC6818为A53架构,改为-mcpu=cortex-a53# 链接选项(链接LVGL库和系统库)
LDFLAGS = -L$(LVGL_DIR)/build/lib \  # LVGL库的编译输出目录-llvgl \                  # 链接LVGL库-lm -lpthread -ldl        # 系统必要库(数学、线程等)# 默认目标:编译生成可执行文件
all: $(TARGET)# 链接目标文件生成可执行文件
$(TARGET): $(OBJS)$(CC) $(OBJS) -o $@ $(LDFLAGS)@echo "编译完成:生成 $(TARGET)"# 编译单个.c文件为.o目标文件
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 清理编译产物(.o文件和可执行文件)
clean:rm -f $(OBJS) $(TARGET)@echo "清理完成"# 伪目标(防止与同名文件冲突)
.PHONY: all clean


2. 使用方法

1. 将 Makefile 放在工程根目录(与 main.c 等文件同级)。

2. 替换 LVGL_DIR = /path/to/your/lvgl 为实际的LVGL库路径(如 ~/lvgl-8.3)。

3. 终端进入工程目录,执行:

◦ 编译:make(生成 login_demo 可执行文件)。

◦ 重新编译:make clean && make。

二、直接使用 arm-linux-gcc 命令编译

无需 Makefile,直接在终端输入完整编译命令(适合快速测试)。

1. 完整编译命令

arm-linux-gcc main.c ui.c user_file.c -o login_demo \
-I/path/to/your/lvgl \
-I/path/to/your/lvgl/src \
-I/path/to/your/lvgl/src/core \
-I/path/to/your/lvgl/src/hal \
-I/path/to/your/lvgl/src/widgets \
-L/path/to/your/lvgl/build/lib \
-llvgl -lm -lpthread -ldl \
-O2 -Wall -mlittle-endian -marm -mcpu=arm926ej-s


2. 命令说明

• 替换路径:将所有 /path/to/your/lvgl 改为你的LVGL库实际路径。

• 参数解释:

◦ -I:指定头文件目录(确保LVGL的 lvgl.h 等能被找到)。

◦ -L:指定LVGL库的存放目录(包含 liblvgl.a 或 liblvgl.so)。

◦ -llvgl:链接LVGL库。

◦ -mcpu=arm926ej-s:适配GEC6818架构(A53架构改为 cortex-a53)。

3. 使用方法

1. 终端进入工程目录(存放 main.c、ui.c、user_file.c)。

2. 粘贴上述命令(替换路径后),回车执行,生成 login_demo。

三、验证与运行

编译成功后,将生成的 login_demo 传输到GEC6818开发板:

1. 赋予执行权限:chmod +x login_demo。

2. 运行程序:./login_demo。

程序会自动创建 users.txt 存储注册信息,界面操作通过触摸完成,输入错误时会弹出 lv_msgbox 提示框。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自媒体端后台设计指南:从注册认证到内容管理的全流程搭建

自媒体端后台设计指南&#xff1a;从注册认证到内容管理的全流程搭建自媒体端后台是专业创作者管理内容、粉丝和数据的核心阵地&#xff0c;其设计直接影响创作效率和平台运营质量。一个功能清晰、操作便捷的后台系统&#xff0c;能让创作者专注于内容生产&#xff0c;而非被复…

uniapp扫描二维码反色处理

在开发扫描二维码过程中&#xff0c;发现白底黑码可以直接用uni.scanCode扫描出来&#xff0c;但是黑底白码就扫不出来&#xff0c;于是就试试反色后的二维码能不能扫描出来&#xff0c;没想到真的可以&#xff0c;下面附上完整代码&#xff1a; <u-icon name"scan&quo…

C语言定义fixed_t什么意思

在 C 语言中&#xff0c;fixed_t 通常是一个自定义的类型别名&#xff08;typedef&#xff09;&#xff0c;用于表示固定点数&#xff08;Fixed-Point Number&#xff09;&#xff0c;而非 C 语言标准库中的原生类型。它主要用于需要高效实数运算但无法使用浮点数的场景&#x…

音频3A处理简介之ANS(自动噪声抑制)

我们常用的手机、消费类摄像头等产品的麦克风所采集的原始声音信号中往往包含了比较多的背景噪音&#xff0c;不仅影响用户录音和回放的使用体验&#xff0c;而且这些噪声数据还会降低音频编码的压缩效率&#xff0c;因此有必要对音频底噪进行抑制处理&#xff0c;这就是ANS&am…

Python 使用期物处理并发(使用concurrent.futures模块启动 进程)

使用concurrent.futures模块启动进程 concurrent.futures 模块的文档 &#xff08;https://docs.python.org/3/library/concurrent.futures.html&#xff09;副标题 是“Launching parallel tasks”&#xff08;执行并行任务&#xff09;。这个模块实现的是真正 的并行计算&…

【系统全面】Linux内核原理——基础知识介绍

理解内核&#xff1a;内核原理 计算机系统的软件分层 不同于单片机中使用代码直接与硬件交互&#xff0c;对于这种方式的缺点深有&#xff1a; &#xff08;1&#xff09;复杂度高&#xff0c;调用难度高&#xff0c;需要深入理解硬件的工作原理和细节。 &#xff08;2&#xf…

Oracle自治事务——从问题到实践的深度解析

一、引言&#xff1a;当“关键操作”遇上主事务的“生死绑定”​先问大家一个问题&#xff1a;假设你在开发一个用户管理系统&#xff0c;核心功能是“用户注册”&#xff0c;同时需要记录“操作日志”。某天&#xff0c;用户提交注册信息时&#xff0c;数据库突然因磁盘空间不…

广播(Broadcast)和组播(Multicast)对比

概述 广播&#xff08;Broadcast&#xff09;和组播&#xff08;Multicast&#xff09;是计算机网络中两种重要的一对多通信方式&#xff0c;用于高效地将数据同时分发给多个接收者&#xff0c;它们的核心区别在于目标接收者的范围和控制精度&#xff0c;基于业务对效率、规模和…

在 HTTP GET 请求中传递参数有两种标准方式

方法 1&#xff1a;URL 查询参数&#xff08;Query Parameters&#xff09;格式&#xff1a;?参数名值&参数名2值2示例请求http://localhost:8080/hello?name张三&age25后端接收方式GetMapping("/hello") public String sayHello(RequestParam String name…

pycharm windows/linux/mac快捷键

适用于mac的快捷键 适用于windows和linux的快捷键 参考资料&#xff1a; https://www.jetbrains.com/zh-cn/help/pycharm/mastering-keyboard-shortcuts.html

前端包管理工具深度对比:npm、yarn、pnpm 全方位解析

前言&#xff1a;为什么我们需要包管理工具&#xff1f; 在现代前端开发中&#xff0c;模块化已成为标配。一个中型项目可能依赖数百个第三方包&#xff0c;手动管理这些依赖几乎是不可能的任务。包管理工具应运而生&#xff0c;它们不仅解决了依赖安装问题&#xff0c;还提供了…

调试Claude code的正确姿势

随着kimi k2的发布&#xff0c;Claude code的使用频率愈发的频繁&#xff0c;在发现moonshot官方提供了调试工具之后&#xff0c;我对claude code的交互过程愈发好奇。 moonpalace的安装 官方moonpalace仓库地址 go语言编写&#xff0c;可以直接下载二进制二进制文件&#x…

【常见分布及其特征(5)】连续型随机变量-连续均匀分布

概率密度函数&#xff08;PDF&#xff09;与概率质量函数&#xff08;PMF&#xff09;说明 基本概念区分 对于连续型随机变量&#xff0c;通常使用 概率密度函数 (Probability Density Function, PDF) 进行描述&#xff1b;这与离散型随机变量使用的 概率质量函数 (Probabili…

FAN-UNET:用于生物医学图像分割增强模型

目录 一、论文结构概述 二、创新点详解 三、创新点结构与原理 &#xff08;1&#xff09;Vision-FAN Block&#xff1a;全局与周期特征的融合引擎 &#xff08;2&#xff09;FANLayer2D&#xff1a;周期性建模的核心 四、代码复现思路 五、仿真结果分析 &#xff08;1&…

基于SpringBoot的篮球运动员体测数据分析及训练管理系统论文

第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各行业&#xff0c;尤其是规模较大的企业和学校等…

矩阵算法题

矩阵算法题1、矩阵置零2、螺旋矩阵3、旋转图像4、搜索二维矩阵1、矩阵置零 解题思路&#xff1a;这道题核心是要确定哪些行和哪些列要置零。所以定义两个数组&#xff0c;一个记录要置零的行&#xff0c;一个记录要置零的列。遍历整个矩阵&#xff0c;如果当前位置是0的话&…

Spring底层(二)Spring IOC容器加载流程原理

一、怎么理解SpringIoc IOC&#xff1a;Inversion Of Control&#xff0c;即控制反转&#xff0c;是一种设计思想。之前对象又程序员自己new自己创建&#xff0c;现在Spring注入给我们&#xff0c;这样的创建权力被反转了。 所谓控制就是对象的创建、初始化、销毁。 创建对象…

UDP中的单播,多播,广播

文章目录UDP 简单回顾一、单播&#xff08;Unicast&#xff09;定义特点应用举例二、广播&#xff08;Broadcast&#xff09;定义特点应用三、多播&#xff08;Multicast&#xff09;定义特点应用UDP 单播、广播、多播的对比总结额外说明代码简要示例&#xff08;C&#xff09;…

数据库练习3

一、建立product表&#xff0c;操作方式operate表要求&#xff1a;1.定义触发器实现在产品表(product)中每多一个产品,就在操作表(operate)中记录操作方式和时间以及编号记录。注&#xff1a;操作说明&#xff1a;标记执行delete 、insert、 update2.定义触发器实现在产品表(pr…

pycharm和anaconda安装,并配置python虚拟环境

1、pycharm和anaconda安装 PyCharm与Anaconda超详细安装配置教程_anaconda pycharm安装-CSDN博客https://blog.csdn.net/qq_32892383/article/details/116137730 2、pycharm汉化 PyCharm汉化&#xff1a;简单两步搞定&#xff01;PyCharm怎么设置中文简体&#xff0c;为什么…