關于基于lvgl庫做的注冊登錄功能的代碼步驟:

以下是完整的文件拆分和代碼存放說明,按功能模塊化劃分,方便工程管理:

一、需要創建的文件清單
文件名 作用 類型?
main.c 程序入口,初始化硬件和LVGL 源文件?
ui.h 聲明界面相關函數 頭文件?
ui.c 實現登錄、注冊、主頁面的UI 源文件?
user_data.h 聲明用戶數據處理函數 頭文件?
user_data.c 實現注冊/登錄的文件讀寫邏輯 源文件?

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

1. main.c(工程入口)存放內容:主函數,初始化硬件、LVGL,啟動界面

#include "lvgl/lvgl.h"
#include "ui.h" ? // 包含界面函數聲明
#include "user_data.h" ?// 包含用戶數據處理聲明// 硬件初始化(需根據GEC6818實際驅動實現)
static void hardware_init(void) {// 此處添加LCD屏幕、觸摸驅動的初始化代碼// 例如:打開LCD設備、設置分辨率、初始化觸摸輸入等
}int main(void) {// 1. 初始化硬件hardware_init();// 2. 初始化LVGLlv_init();lv_port_disp_init(); ?// 顯示接口初始化(適配GEC6818 LCD)lv_port_indev_init(); // 輸入設備初始化(適配觸摸)// 3. 初始化用戶數據(如檢查存儲文件是否存在)// (可選,user_data.c中若有初始化邏輯可在此調用)// 4. 顯示初始界面(登錄頁)create_login_ui();// 5. LVGL主循環while (1) {lv_task_handler(); ?// 處理LVGL任務usleep(5000); ? ? ? // 5ms延遲}return 0;
}


2. ui.h(界面函數聲明)存放內容:聲明所有界面創建和回調函數

#ifndef UI_H
#define UI_H#include "lvgl/lvgl.h"// 登錄界面
void create_login_ui(void);// 注冊界面
void create_reg_ui(void);// 主頁面(登錄成功后顯示)
void switch_to_main_page(lv_timer_t *t);// 注冊成功后返回登錄頁
void back_to_login(lv_timer_t *t);#endif // UI_H


3. ui.c(界面實現)存放內容:登錄/注冊/主頁面的LVGL組件創建,按鈕回調邏輯

#include "ui.h"
#include "user_data.h" ?// 調用注冊/登錄函數// 登錄界面輸入緩存
static char username[32] = "";
static char password[32] = "";// 注冊界面輸入緩存
static char reg_username[32] = "";
static char reg_password[32] = "";// 登錄界面創建
void create_login_ui(void) {// 清空當前界面lv_obj_clean(lv_scr_act());// 1. 創建主頁面容器lv_obj_t *page = lv_obj_create(lv_scr_act());lv_obj_set_size(page, LV_HOR_RES, LV_VER_RES);// 2. 賬號輸入框lv_obj_t *user_label = lv_label_create(page);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(page);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, username);// 3. 密碼輸入框lv_obj_t *pwd_label = lv_label_create(page);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(page);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, password);// 4. 登錄按鈕及回調lv_obj_t *login_btn = lv_btn_create(page);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, NULL);// 5. 注冊按鈕(跳轉到注冊界面)lv_obj_t *to_reg_btn = lv_btn_create(page);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 *title = lv_label_create(lv_scr_act());lv_label_set_text(title, "用戶注冊");lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 50);// 2. 注冊賬號輸入框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_username);// 3. 注冊密碼輸入框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_password);// 4. 注冊按鈕及回調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, NULL);// 5. 返回登錄按鈕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_btn_label = lv_label_create(back_btn);lv_label_set_text(back_btn_label, "返回登錄");lv_obj_add_event_cb(back_btn, back_to_login_cb, LV_EVENT_CLICKED, NULL);
}// 登錄按鈕回調
static void login_btn_cb(lv_event_t *e) {// 獲取輸入框內容lv_obj_t *user_ta = lv_obj_get_child(lv_scr_act(), 1); ?// 賬號輸入框lv_obj_t *pwd_ta = lv_obj_get_child(lv_scr_act(), 3); ? // 密碼輸入框const char *user = lv_textarea_get_text(user_ta);const char *pwd = lv_textarea_get_text(pwd_ta);// 調用登錄驗證函數(來自user_data.c)int ret = login_user(user, pwd);lv_obj_t *msg;if (ret == 0) {msg = lv_msgbox_create(NULL, "提示", "登錄成功!", NULL, false);lv_timer_create(switch_to_main_page, 1500, NULL); ?// 跳轉主頁面} else if (ret == -1) {msg = lv_msgbox_create(NULL, "提示", "暫無注冊用戶,請先注冊", NULL, false);} else {msg = lv_msgbox_create(NULL, "提示", "賬號或密碼錯誤", NULL, false);}lv_obj_center(msg);
}// 注冊按鈕回調
static void reg_btn_cb(lv_event_t *e) {// 獲取注冊輸入框內容lv_obj_t *reg_user_ta = lv_obj_get_child(lv_scr_act(), 1); ?// 新賬號輸入框lv_obj_t *reg_pwd_ta = lv_obj_get_child(lv_scr_act(), 3); ? // 新密碼輸入框const char *user = lv_textarea_get_text(reg_user_ta);const char *pwd = lv_textarea_get_text(reg_pwd_ta);// 調用注冊函數(來自user_data.c)int ret = register_user(user, pwd);lv_obj_t *msg;if (ret == 0) {msg = lv_msgbox_create(NULL, "提示", "注冊成功!", NULL, false);lv_timer_create(back_to_login, 1500, NULL); ?// 返回登錄頁} 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 back_to_login_cb(lv_event_t *e) {create_login_ui();
}// 登錄成功后跳轉主頁面
void switch_to_main_page(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 back_to_login(lv_timer_t *t) {create_login_ui();
}


4. user_data.h(用戶數據函數聲明)存放內容:聲明注冊、登錄、賬號檢查等函數

#ifndef USER_DATA_H
#define USER_DATA_H#include <stdio.h>// 注冊用戶(返回0成功,-1空輸入,-2賬號已存在,-3文件錯誤)
int register_user(const char *username, const char *password);// 登錄驗證(返回0成功,-1無注冊用戶,-2賬號密碼錯誤)
int login_user(const char *username, const char *password);#endif // USER_DATA_H


5. user_data.c(用戶數據處理)存放內容:文件讀寫邏輯,實現注冊和登錄的核心驗證

#include "user_data.h"
#include <string.h>// 存儲用戶信息的文件路徑
#define USER_FILE "users.txt"// 檢查賬號是否已存在
static int is_username_exist(const char *username) {FILE *fp = fopen(USER_FILE, "r");if (!fp) return 0; ?// 文件不存在,無重復char line[128], u[32];while (fgets(line, sizeof(line), fp)) {if (sscanf(line, "%31[^:]", u) == 1 && strcmp(u, username) == 0) {fclose(fp);return 1; ?// 賬號已存在}}fclose(fp);return 0;
}// 注冊函數:寫入文件
int register_user(const char *username, const char *password) {// 檢查輸入合法性if (strlen(username) == 0 || strlen(password) == 0) return -1;if (is_username_exist(username)) return -2;// 寫入文件(追加模式)FILE *fp = fopen(USER_FILE, "a");if (!fp) return -3;fprintf(fp, "%s:%s\n", username, password); ?// 實際需加密存儲fclose(fp);return 0;
}// 登錄函數:讀取文件比對
int login_user(const char *username, const char *password) {FILE *fp = fopen(USER_FILE, "r");if (!fp) return -1; ?// 無注冊用戶char line[128], u[32], p[32];while (fgets(line, sizeof(line), fp)) {if (sscanf(line, "%31[^:]:%31s", u, p) == 2) {if (strcmp(u, username) == 0 && strcmp(p, password) == 0) {fclose(fp);return 0; ?// 登錄成功}}}fclose(fp);return -2; ?// 賬號或密碼錯誤
}


三、工程文件結構
project/
├── main.c ? ? ? ? ?# 主程序入口
├── ui.h ? ? ? ? ? ?# 界面函數聲明
├── ui.c ? ? ? ? ? ?# 登錄/注冊界面實現
├── user_data.h ? ? # 數據處理函數聲明
├── user_data.c ? ? # 注冊/登錄文件讀寫邏輯
└── Makefile ? ? ? ?# 編譯配置(需自行編寫,鏈接LVGL庫)
四、編譯說明

? 編譯時需鏈接LVGL庫(-llvgl),確保GEC6818的交叉編譯環境正確配置。

? 運行后會在程序目錄自動生成users.txt文件,存儲注冊的賬號密碼。

按此結構存放代碼,可實現模塊化管理,方便后續修改界面或數據存儲邏輯。


如果你的交叉編譯工具鏈是 arm-linux-gcc(而非 arm-linux-gnueabihf-gcc),只需調整 Makefile 中的工具鏈和編譯選項即可。以下是適配 arm-linux-gcc 的版本,可直接使用:適配 arm-linux-gcc 的 Makefile

# 交叉編譯工具鏈(使用arm-linux-gcc)
CC = arm-linux-gcc# LVGL庫路徑(替換為你的LVGL實際路徑)
LVGL_DIR = /path/to/your/lvgl# 源文件列表
SRCS = main.c ui.c user_data.c# 目標文件
OBJS = $(SRCS:.c=.o)# 生成的可執行文件名
TARGET = login_demo# 編譯選項(適配arm-linux-gcc,無需硬浮點參數)
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若基于ARM9架構,用此參數;若為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 $@# 清理編譯產物
clean:rm -f $(OBJS) $(TARGET)@echo "清理完成".PHONY: all clean


關鍵調整說明

1. 工具鏈修改:將 CC 改為 arm-linux-gcc,匹配你的工具鏈。

2. 架構參數:

? 若GEC6818基于 ARM9 架構(部分版本),使用 -mcpu=arm926ej-s。

? 若基于 Cortex-A53 架構,保留 -mcpu=cortex-a53 即可。

3. 去除硬浮點參數:arm-linux-gcc 通常不默認支持 neon-vfpv4 等硬浮點選項,因此刪除 -mfpu=neon-vfpv4 和 -mfloat-abi=hard。

使用方法

1. 替換 LVGL_DIR 為你的LVGL庫實際路徑(例如 ~/lvgl)。

2. 終端進入工程目錄,執行 make 編譯,生成 login_demo。

3. 傳輸到開發板后,執行 chmod +x login_demo 賦予權限,再運行 ./login_demo。

如果編譯時出現架構不匹配的錯誤,可嘗試刪除 -mcpu=xxx 選項,或根據開發板CPU型號調整。


如果直接用 arm-linux-gcc 命令編譯(不通過 Makefile),可以執行以下完整命令(需根據你的實際路徑調整):

arm-linux-gcc main.c ui.c user_data.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


命令說明(按順序):

1. 編譯源文件:main.c ui.c user_data.c 是工程的所有源文件。

2. 指定輸出文件名:-o login_demo 表示生成名為 login_demo 的可執行文件。

3. LVGL頭文件路徑:-I/path/to/your/lvgl 及后續 -I 選項,替換為你的LVGL庫實際路徑(需包含所有LVGL的頭文件目錄)。

4. LVGL庫路徑:-L/path/to/your/lvgl/build/lib 替換為LVGL庫編譯后的輸出目錄(包含 liblvgl.a 或 liblvgl.so)。

5. 鏈接庫:-llvgl 鏈接LVGL庫;-lm -lpthread -ldl 鏈接系統必要的數學庫、線程庫等。

6. 編譯選項:-O2 優化編譯;-Wall 顯示警告;-mlittle-endian -marm -mcpu=arm926ej-s 適配GEC6818架構(若為A53,可將 arm926ej-s 改為 cortex-a53)。

使用步驟:

1. 打開終端,進入存放 main.c、ui.c、user_data.c 的工程目錄。

2. 將上述命令中的 /path/to/your/lvgl 替換為你的LVGL庫實際路徑(例如 ~/lvgl-8.3)。

3. 粘貼并執行命令,編譯成功后會生成 login_demo 文件。

4. 傳輸到GEC6818開發板,執行 chmod +x login_demo 后,運行 ./login_demo 即可。

如果編譯報錯“找不到頭文件”或“找不到庫”,檢查路徑是否正確;若報架構錯誤,調整 -mcpu 參數即可。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89650.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89650.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89650.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RAII機制以及在ROS的NodeHandler中的實現

好的&#xff0c;這是一個非常核心且優秀的設計問題。我們來分兩步詳細解析&#xff1a;先徹底搞懂什么是 RAII&#xff0c;然后再看 ros::NodeHandle 是如何巧妙地運用這一機制的。1. 什么是 RAII 機制&#xff1f; RAII 是 “Resource Acquisition Is Initialization” 的縮寫…

Linux LVS集群技術

LVS集群概述1、集群概念1.1、介紹集群是指多臺服務器集中在一起&#xff0c;實現同一業務&#xff0c;可以視為一臺計算機。多臺服務器組成的一組計算機&#xff0c;作為一個整體存在&#xff0c;向用戶提供一組網絡資源&#xff0c;這些單個的服務器就是集群的節點。特點&…

spring-ai-alibaba如何上傳文件并解析

問題引出 在我們日常使用大模型時&#xff0c;有一類典型的應用場景&#xff0c;就是將文件發送給大模型&#xff0c;然后由大模型進行解析&#xff0c;提煉總結等&#xff0c;這一類功能在官方app中較為常見&#xff0c;但是在很多模型的api中都不支持&#xff0c;那如何使用…

「雙容器嵌套布局法」:打造清晰層級的網頁架構設計

一、命名與核心概念 “雙容器嵌套布局法”&#xff0c;核心是通過兩層容器嵌套構建網頁結構&#xff1a;外層容器負責控制布局的“宏觀約束”&#xff08;如頁面最大寬度、背景色等&#xff09;&#xff0c;內層容器聚焦“微觀排版”&#xff08;內容居中、內邊距調整、紅色內容…

基于深度學習的自然語言處理:構建情感分析模型

前言 自然語言處理&#xff08;NLP&#xff09;是人工智能領域中一個非常活躍的研究方向&#xff0c;它致力于使計算機能夠理解和生成人類語言。情感分析&#xff08;Sentiment Analysis&#xff09;是NLP中的一個重要應用&#xff0c;其目標是從文本中識別和提取情感傾向&…

JWT原理及利用手法

JWT 原理 JSON Web Token (JWT) 是一種開放的行業標準&#xff0c;用于在系統之間以 JSON 對象的形式安全地傳輸信息。這些信息經過數字簽名&#xff0c;因此可以被驗證和信任。其常用于身份驗證、會話管理和訪問控制機制中傳遞用戶信息。 與傳統的會話令牌相比&#xff0c;JWT…

DeepSeek 助力 Vue3 開發:打造絲滑的日歷(Calendar),日歷_睡眠記錄日歷示例(CalendarView01_30)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄DeepS…

git的diff命令、Config和.gitignore文件

diff命令&#xff1a;比較git diff xxx&#xff1a;工作目錄 vs 暫存區&#xff08;比較現在修改之后的工作區和暫存區的內容&#xff09;git diff --cached xxx&#xff1a;暫存區 vs Git倉庫&#xff08;現在暫存區內容和最一開始提交的文件內容的比較&#xff09;git diff H…

Linux中的LVS集群技術

一、實驗環境&#xff08;RHEL 9&#xff09;1、NAT模式的實驗環境主機名IP地址網關網絡適配器功能角色client172.25.254.111/24&#xff08;NAT模式的接口&#xff09;172.25.254.2NAT模式客戶機lvs172.25.254.100/24&#xff08;NAT模式的接口&#xff09;192.168.0.100/24&a…

【數據結構】「隊列」(順序隊列、鏈式隊列、雙端隊列)

- 第 112篇 - Date: 2025 - 07 - 20 Author: 鄭龍浩&#xff08;仟墨&#xff09; 文章目錄隊列&#xff08;Queue&#xff09;1 基本介紹1.1 定義1.2 棧 與 隊列的區別1.3 重要術語2 基本操作3 順序隊列(循環版本)兩種版本兩種版本區別版本1.1 - rear指向隊尾后邊 且 無 size …

Java行為型模式---解釋器模式

解釋器模式基礎概念解釋器模式&#xff08;Interpreter Pattern&#xff09;是一種行為型設計模式&#xff0c;其核心思想是定義一個語言的文法表示&#xff0c;并定義一個解釋器&#xff0c;使用該解釋器來解釋語言中的句子。這種模式將語法解釋的責任分開&#xff0c;使得語法…

[spring6: PointcutAdvisor MethodInterceptor]-簡單介紹

Advice Advice 是 AOP 聯盟中所有增強&#xff08;通知&#xff09;類型的標記接口&#xff0c;表示可以被織入目標對象的橫切邏輯&#xff0c;例如前置通知、后置通知、異常通知、攔截器等。 package org.aopalliance.aop;public interface Advice {}BeforeAdvice 前置通知的標…

地圖定位與導航

定位 1.先申請地址權限(大致位置精準位置) module.json5文件 "requestPermissions": [{"name": "ohos.permission.INTERNET" },{"name": "ohos.permission.LOCATION","reason": "$string:app_name",&qu…

【數據結構】揭秘二叉樹與堆--用C語言實現堆

文章目錄1.樹1.1.樹的概念1.2.樹的結構1.3.樹的相關術語2.二叉樹2.1.二叉樹的概念2.2.特殊的二叉樹2.2.1.滿二叉樹2.2.2.完全二叉樹2.3.二叉樹的特性2.4.二叉樹的存儲結構2.4.1.順序結構2.4.2.鏈式結構3.堆3.1.堆的概念3.2.堆的實現3.2.1.堆結構的定義3.2.2.堆的初始化3.2.3.堆…

區間樹:多維數據的高效查詢

區間樹&#xff1a;多維數據的高效查詢 大家好&#xff0c;今天我們來探討一個在計算機科學中非常有趣且實用的數據結構——區間樹。想象一下&#xff0c;你是一位城市規劃師&#xff0c;需要快速找出某個區域內所有的醫院、學校或商場。或者你是一位游戲開發者&#xff0c;需要…

SQL 魔法:LEFT JOIN 與 MAX 的奇妙組合

一、引言 在數據庫操作的領域中&#xff0c;數據的關聯與聚合處理是核心任務之一。LEFT JOIN作為一種常用的連接方式&#xff0c;能夠將左表中的所有記錄與右表中滿足連接條件的記錄進行關聯&#xff0c;即便右表中沒有匹配的記錄&#xff0c;左表的記錄也會被保留&#xff0c;…

手寫tomcat

package com.qcby.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;Target(ElementType.TYPE)// 表示該注解只能用于類上 Retention(Retentio…

Android平臺下openssl動態庫編譯

1. 下載Linux平臺下的NDK軟件包 NDK 下載 | Android NDK | Android Developers 下載完成后執行解壓命令 # unzip android-ndk-r27d-linux.zip 2. 下載openssl-1.1.1w源碼包&#xff0c;并解壓 # tar -xzvf openssl-1.1.1w.tar.gz 3. 進入解壓后的openssl-1.1.1w目錄 …

【C++基礎】面試高頻考點解析:extern “C“ 的鏈接陷阱與真題實戰

名稱修飾&#xff08;Name Mangling&#xff09;是C為支持重載付出的代價&#xff0c;而extern "C"則是跨越語言邊界的橋梁——但橋上的陷阱比橋本身更值得警惕 一、extern "C" 的核心概念與高頻考點1.1 鏈接規范與名字改編機制C 為支持函數重載&#xff0…

OpenCV 官翻 4 - 相機標定與三維重建

文章目錄相機標定目標基礎原理代碼配置校準去畸變1、使用 cv.undistort()2、使用**重映射**方法重投影誤差練習姿態估計目標基礎渲染立方體極線幾何目標基礎概念代碼練習從立體圖像生成深度圖目標基礎概念代碼附加資源練習相機標定 https://docs.opencv.org/4.x/dc/dbb/tutori…