嵌入式培訓之數據結構學習(五)棧與隊列

一、棧

(一)棧的基本概念

1、棧的定義:

注:線性表中的棧在堆區(因為是malloc來的);系統中的棧區存儲局部變量、函數形參、函數返回值地址。

2、棧頂和棧底:

????????允許插入和刪除的一端稱為棧頂(top),另一端稱為棧底(bottom),不含任何數據元素的棧稱為空棧。

3、 LIFO 結構:棧又稱為后進先出(LastInFirst0ut)的線性表。

4、棧示意圖:

top為棧頂指針

5、棧對線性表的插入和刪除的位置進行了限制,并沒有對元素進出的時間進行限制

也就是說,在不是所有元素都進棧的情況下,事先進去的元素也可以出棧,只要保證是

棧頂元素出棧就可以。

6、應用:解決的問題要回溯、遞歸可以用鏈棧;

? ? ? ? ? ? ? ?有優先級問題的用棧處理

(1)直觀應用(eg:gdb調試中的where命令):函數調用返回原函數用棧結構(一層

一層進、一層一層退);

(2)(3 + 5 * 6)四則運算表達式

優先級問題、字符串解析(先掃一遍表達式,再套用優先級順序對優先級高的優先處理,最后在退回來處理表達式)。

(二)鏈棧的基本操作

1、創建鏈棧

LinkStack* CreateLinkStack()?
{?
? ? // 分配鏈棧結構體空間,void* 強轉為 LinkStack*?
? ? LinkStack* ls = (LinkStack*)malloc(sizeof(LinkStack));?
? ? if(NULL == ls)?
? ? {?
? ? ? ? // 打印錯誤信息到標準錯誤流?
? ? ? ? fprintf(stderr,"CreateLinkStack malloc\n");?
? ? ? ? return NULL; // 分配失敗返回空?
? ? }?
? ? ls->top = NULL; // 初始化棧頂指針為空(空棧)?
? ? ls->clen = 0; // 初始化棧長度為0?
? ? return ls; // 返回創建好的鏈棧指針?
}

2、入棧

int PushLinkStack(LinkStack* ls, DATATYPE* data)?
{?
? ? // 分配新節點空間?
? ? LinkStackNode* newnode = malloc(sizeof(LinkStackNode));?
? ? if(NULL == newnode)?
? ? {?
? ? ? ? fprintf(stderr,"PushLinkStack malloc\n"); // 打印內存分配失敗信息?
? ? ? ? return 1; // 失敗返回錯誤碼1?
? ? }?
? ? // 將數據拷貝到新節點的數據域?
? ? memcpy(&newnode->data, data, sizeof(DATATYPE));?
? ? newnode->next = NULL; // 新節點初始next指針為空?
? ? newnode->next = ls->top; // 新節點next指向原棧頂節點(頭插法)?
? ? ls->top = newnode; // 棧頂更新為新節點?
? ? ls->clen++; // 棧長度加1?
? ? return 0; // 成功返回0(原代碼缺失return,需補充)
}

3、出棧

int PopLinkStack(LinkStack* ls)?
{?
? ? if(IsEmptyLinkStack(ls)) // 檢查棧是否為空?
? ? {?
? ? ? ? return 1; // 空棧返回錯誤碼1?
? ? }?
? ? LinkStackNode* tmp = ls->top; // 保存當前棧頂節點指針?
? ? ls->top = ls->top->next; // 棧頂指針后移一位(指向原次棧頂)?
? ? free(tmp); // 釋放原棧頂節點內存?
? ? ls->clen--; // 棧長度減1?
? ? return 0; // 成功返回0?
}

4、判斷棧空

int IsEmptyLinkStack(LinkStack* ls)?
{?
? ? // 棧長度為0時返回1(真),否則返回0(假)?
? ? return 0 == ls->clen;?
}

5、獲取棧頂元素

DATATYPE* GetTopLinkStack(LinkStack* ls)?
{?
? ? if(IsEmptyLinkStack(ls)) // 檢查棧是否為空?
? ? {?
? ? ? ? return NULL; // 空棧返回空指針?
? ? }?
? ? // 返回棧頂節點數據域的地址(需確保調用時不為空)?
? ? return &ls->top->data;?
}

6、銷毀鏈棧

int DestroyLinkStack(LinkStack* ls)?
{?
? ? int len = GetSizeLinkStack(ls); // 獲取棧當前長度?
? ? for(int i = 0; i < len; ++i)?
? ? {?
? ? ? ? PopLinkStack(ls); // 循環調用出棧函數釋放所有節點?
? ? }?
? ? free(ls); // 釋放鏈棧結構體本身的內存?
? ? return 0; // 成功返回0?
}

注:查看是否內存泄漏:valgrind? ./app

7、獲取棧長度

int GetSizeLinkStack(LinkStack* ls)?
{?
? ? // 直接返回結構體中記錄的棧長度(O(1)時間復雜度)?
? ? return ls->clen;?
}

(三)棧練習:C語言文本檢查器(符號匹配)

1、代碼:

(1)文件讀取函數 readfile
?int readfile(char *filename, char *filecontext)?
{?
? ? // 以只讀模式打開文件?
? ? FILE *fp = fopen(filename, "r");?
? ? if (NULL == fp)?
? ? {?
? ? ? ? return 1; // 打開失敗返回1?
? ? }?
? ? // 從文件讀取1024字節到filecontext緩沖區,返回實際讀取塊數(此處塊大小為1字節)?
? ? fread(filecontext, 1024, 1, fp);?
? ? fclose(fp); // 關閉文件?
? ? return 0; // 成功返回0?
}

(2) 主函數 main
?
int main(int argc, char **argv)?
{?
? ? char buf[1024] = {0}; // 初始化1024字節緩沖區?
? ? int ret = readfile("/home/linux/2.c", buf); // 讀取文件內容到buf?
? ? if (1 == ret)?
? ? {?
? ? ? ? return 1; // 讀取失敗直接退出?
? ? }?

? ? LinkStack *ls = CreateLinkStack(); // 創建鏈棧用于符號匹配?
? ? char *tmp = buf; // 臨時指針指向緩沖區起始位置?
? ? DATATYPE data = {0}; // 存儲符號及其行列信息的結構體?
? ? int row = 1; // 當前行號,初始為1?
? ? int col = 1; // 當前列號,初始為1?
? ? DATATYPE *top; // 用于存儲棧頂元素的指針?

? ? while (*tmp) // 遍歷緩沖區直到遇到'\0'?
? ? {?
? ? ? ? memset(&data, 0, sizeof(DATATYPE)); // 清空結構體數據?
? ? ? ? switch (*tmp) // 根據當前字符判斷類型?
? ? ? ? {
? ? ? ? ? ? // 處理左括號:( [ {
? ? ? ? ? ? case '(':?
? ? ? ? ? ? case '[':?
? ? ? ? ? ? case '{':?
? ? ? ? ? ? ? ? data.c = *tmp; // 存儲符號?
? ? ? ? ? ? ? ? data.col = col; // 存儲列號?
? ? ? ? ? ? ? ? data.row = row; // 存儲行號?
? ? ? ? ? ? ? ? PushLinkStack(ls, &data); // 將符號入棧?
? ? ? ? ? ? ? ? break;

? ? ? ? ? ? // 處理右括號:)
? ? ? ? ? ? case ')':?
? ? ? ? ? ? ? ? top = GetTopLinkStack(ls); // 獲取棧頂元素?
? ? ? ? ? ? ? ? // 棧頂存在且為匹配的'('?
? ? ? ? ? ? ? ? if ('(' == top->c && NULL != top)?
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? PopLinkStack(ls); // 匹配成功,出棧?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? if (NULL == top) // 棧空,說明缺少左括號?
? ? ? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? ? ? // 輸出錯誤:右括號無匹配左括號?
? ? ? ? ? ? ? ? ? ? ? ? printf("sym:%c row:%d col%d\n", ')', row, col);?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? else // 棧頂符號不匹配(如棧頂是'['或'{')?
? ? ? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? ? ? // 輸出錯誤:棧頂符號與當前右括號不匹配?
? ? ? ? ? ? ? ? ? ? ? ? printf(
? ? ? ? ? ? ? ? ? ? ? ? ? ? "top sym:%c row:%d col%d , or file sym:%c row:%d col%d\n",?
? ? ? ? ? ? ? ? ? ? ? ? ? ? top->c, top->row, top->col, *tmp, row, col);?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? return 1; // 匹配失敗,程序退出?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? break;

? ? ? ? ? ? // 處理右括號:](邏輯同')')
? ? ? ? ? ? case ']':?
? ? ? ? ? ? ? ? top = GetTopLinkStack(ls);?
? ? ? ? ? ? ? ? if ('[' == top->c && NULL != top)?
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? PopLinkStack(ls);?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? if (NULL == top)?
? ? ? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? ? ? printf("sym:%c row:%d col%d\n", ']', row, col); // 注意此處誤寫為')',應為']'?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? ? ? printf(
? ? ? ? ? ? ? ? ? ? ? ? ? ? "top sym:%c row:%d col%d , or file sym:%c row:%d col%d\n",?
? ? ? ? ? ? ? ? ? ? ? ? ? ? top->c, top->row, top->col, *tmp, row, col);?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? return 1;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? break;

? ? ? ? ? ? // 處理右括號:}(邏輯同')')
? ? ? ? ? ? case '}':?
? ? ? ? ? ? ? ? top = GetTopLinkStack(ls);?
? ? ? ? ? ? ? ? if ('{' == top->c && NULL != top)?
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? PopLinkStack(ls);?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? if (NULL == top)?
? ? ? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? ? ? printf("sym:%c row:%d col%d\n", '}', row, col); // 注意此處誤寫為')',應為'}'?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? ? ? printf(
? ? ? ? ? ? ? ? ? ? ? ? ? ? "top sym:%c row:%d col%d , or file sym:%c row:%d col%d\n",?
? ? ? ? ? ? ? ? ? ? ? ? ? ? top->c, top->row, top->col, *tmp, row, col);?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? return 1;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? break;
? ? ? ? }

? ? ? ? col++; // 列號遞增?
? ? ? ? if ('\n' == *tmp) // 遇到換行符?
? ? ? ? {?
? ? ? ? ? ? col = 1; // 列號重置為1?
? ? ? ? ? ? row++; // 行號遞增?
? ? ? ? }?
? ? ? ? tmp++; // 移動到下一個字符?
? ? }

? ? // 遍歷結束后檢查棧是否為空(所有左括號是否匹配)
? ? if ('\0' == *tmp && IsEmptyLinkStack(ls))?
? ? {?
? ? ? ? printf("ok"); // 完全匹配,輸出"ok"?
? ? }?
? ? else?
? ? {?
? ? ? ? top = GetTopLinkStack(ls); // 獲取剩余未匹配的左括號?
? ? ? ? // 輸出未匹配的左括號及其位置?
? ? ? ? printf("top sym:%c row:%d col%d\n", top->c, top->row, top->col);?
? ? }

? ? DestroyLinkStack(ls); // 銷毀鏈棧,釋放內存?
? ? return 0;?
}

2、輸出結果:匹配成功輸出ok,匹配不成功輸出符號及其位置。

二、隊列

(一)隊列的基本概念

1、隊列的定義:

2、FIFO結構:隊列是一種先進先出(FirstInFirst0ut)的線性表。

? ? ?允許插入的一 端稱為隊尾,允許刪除的一端稱為隊頭。

3、隊列示意圖

clen = (尾巴 - 頭 + 長度)

4、應用:計算機做緩沖用隊列;

5、循環隊列(圓環):(求余就循環起來)

6、面試問題:滿隊判斷條件:尾巴+1==頭? ?(tail + 1 ) % tlen == head

? ? ? ? ? ? ? ? ? ? ? ?空隊:尾巴==頭? ?tail == head

(二)隊列的基本操作

1、創建順序隊列

SeqQueue* CreateSeqQue(int len)?
{?
? ? // 分配順序隊列結構體空間,強轉為 SeqQueue*?
? ? SeqQueue* sq = (SeqQueue*)malloc(sizeof(SeqQueue));?
? ? if(NULL == sq)?
? ? {?
? ? ? ? // 打印結構體內存分配失敗信息到標準錯誤流?
? ? ? ? fprintf(stderr,"CreateSeqQue malloc\n");?
? ? ? ? return NULL; // 失敗返回空?
? ? }?
? ? // 分配隊列數據存儲數組空間(容量為len)?
? ? sq->array = malloc(sizeof(DATATYPE)*len);?
? ? if(NULL == sq->array)?
? ? {?
? ? ? ? // 打印數組內存分配失敗信息?
? ? ? ? fprintf(stderr,"CreateSeqQue malloc\n");?
? ? ? ? free(sq); // 釋放已分配的結構體空間(避免內存泄漏)?
? ? ? ? return NULL;?
? ? }?
? ? sq->head = 0; // 初始化頭指針(指向隊頭元素前一個位置)?
? ? sq->tail = 0; // 初始化尾指針(指向隊尾元素位置)?
? ? sq->tlen = len; // 記錄隊列總長度(容量)?
? ? return sq; // 返回創建好的順序隊列指針?
}

2、判斷隊空

int IsEmptySeqQue(SeqQueue* sq)?
{?
? ? // 頭指針等于尾指針時隊列為空(返回1表示真,0表示假)?
? ? return sq->head == sq->tail;?
}

3、判斷隊滿

int IsFullSeqQue(SeqQueue* sq)?
{?
? ? // 尾指針下一個位置(循環取模)等于頭指針時隊滿?
? ? return (sq->tail + 1) % sq->tlen == sq->head;?
}

4、入隊

int EnterSeqQue(SeqQueue* sq, DATATYPE* data)?
{?
? ? if(IsFullSeqQue(sq))?
? ? {?
? ? ? ? // 打印隊滿錯誤信息?
? ? ? ? fprintf(stderr,"EnterSeqQue,SeqQueue full\n");?
? ? ? ? return 1; // 失敗返回錯誤碼1?
? ? }?
? ? // 將數據拷貝到尾指針當前位置的數組元素中?
? ? memcpy(&sq->array[sq->tail], data, sizeof(DATATYPE));?
? ? // 尾指針后移一位(循環隊列,取模實現環形)?
? ? sq->tail = (sq->tail + 1) % sq->tlen;?
? ? return 0; // 成功返回0?
}

5、出隊

int QuitSeqQue(SeqQueue* sq)?
{?
? ? if(IsEmptySeqQue(sq))?
? ? {?
? ? ? ? // 打印隊空錯誤信息?
? ? ? ? fprintf(stderr,"QuitSeqQue SeqQueue empty\n");?
? ? ? ? return 1; // 失敗返回錯誤碼1?
? ? }?
? ? // 頭指針后移一位(指向實際隊頭元素,取模實現環形)?
? ? sq->head = (sq->head + 1) % sq->tlen;?
? ? return 0; // 成功返回0?
}

6、獲取隊頭元素

DATATYPE* GetHeadSeqQue(SeqQueue* sq)?
{?
? ? if(IsEmptySeqQue(sq))?
? ? {?
? ? ? ? return NULL; // 隊空返回空指針?
? ? }?
? ? // 返回隊頭元素地址(頭指針當前指向的是隊頭元素的位置)?
? ? return &sq->array[sq->head];?
}

7、銷毀順序隊列

int DestroySeqQue(SeqQueue* sq)?
{?
? ? free(sq->array); // 先釋放數據存儲數組的內存?
? ? free(sq); // 再釋放隊列結構體的內存?
? ? return 0; // 成功返回0?
}

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

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

相關文章

深度學習---知識蒸餾(Knowledge Distillation, KD)

一、知識蒸餾的本質與起源 定義&#xff1a; 知識蒸餾是一種模型壓縮與遷移技術&#xff0c;通過將復雜高性能的教師模型&#xff08;Teacher Model&#xff09;所學的“知識”遷移到輕量級的學生模型&#xff08;Student Model&#xff09;&#xff0c;使學生模型在參數量和計…

ARP Detection MAC-Address Static

一、ARP Detection&#xff08;ARP檢測&#xff09; ? 定義&#xff1a; ARP檢測是一種防止ARP欺騙攻擊的安全機制。它通過監控或驗證網絡中的ARP報文&#xff0c;來判斷是否存在偽造的ARP信息。 &#x1f50d; 工作原理&#xff1a; 網絡設備&#xff08;如交換機&#xf…

基于 Python 的界面程序復現:標準干涉槽型設計計算及仿真

基于 Python 的界面程序復現&#xff1a;標準干涉槽型設計計算及仿真 在工業設計與制造領域&#xff0c;刀具的設計與優化是提高生產效率和產品質量的關鍵環節之一。本文將介紹如何使用 Python 復現一個用于標準干涉槽型設計計算及仿真的界面程序&#xff0c;旨在幫助工程師和…

Python繪制南丁格爾玫瑰圖:從入門到實戰

Python繪制南丁格爾玫瑰圖&#xff1a;從入門到實戰 引言 南丁格爾玫瑰圖&#xff08;Nightingale Rose Chart&#xff09;&#xff0c;也被稱為極區圖&#xff08;Polar Area Chart&#xff09;&#xff0c;是一種獨特的數據可視化方式。這種圖表由弗洛倫斯南丁格爾&#xff…

計算機操作系統概要

不謀萬世者&#xff0c;不?謀?時。不謀全局者 &#xff0c;足謀?域 。 ——陳澹然《寤?》《遷都建藩議》 操作系統 一.對文件簡單操作的常用基礎指令 ls ls 選項 目錄或?件名:羅列當前?錄下的?件 -l&#xff1a;以長格式顯示?件和?錄的詳細信息 -a 或 --all&…

<PLC><視覺><機器人>基于海康威視視覺檢測和UR機械臂,如何實現N點標定?

前言 本系列是關于PLC相關的博文,包括PLC編程、PLC與上位機通訊、PLC與下位驅動、儀器儀表等通訊、PLC指令解析等相關內容。 PLC品牌包括但不限于西門子、三菱等國外品牌,匯川、信捷等國內品牌。 除了PLC為主要內容外,相關設備如觸摸屏(HMI)、交換機等工控產品,如果有…

從專家編碼到神經網絡學習:DTM 的符號操作新范式

1st author: Paul Soulos paper: Differentiable Tree Operations Promote Compositional Generalization ICML 2023 code: psoulos/dtm: Differentiable Tree Machine 1. 問題與思路 現代深度學習在連續向量空間中取得了巨大成功&#xff0c;然而在處理具有顯式結構&#x…

微信小程序第三方代開發模式技術調研與實踐總結

?? 微信小程序第三方代開發模式技術調研與實踐總結 ?? 前言 隨著企業對私有化品牌運營訴求的增加,許多大型客戶希望將原本由 SaaS 平臺統一提供的小程序遷移至自有主體(AppID)下運行,同時又希望繼續沿用 SaaS 平臺的業務服務與數據托管方式。微信開放平臺提供的“小程…

開啟智能未來:DeepSeek賦能行業變革之路

前言 在人工智能重構生產關系的2025年&#xff0c;DeepSeek以其革命性的推理能力和Python生態的技術延展性&#xff0c;正在重塑內容創作與數據智能的邊界。本書以"工具迭代思維升維"為雙輪驅動&#xff0c;構建從認知突破到商業落地的完整知識圖譜。 DeepSeek的崛…

常見三維引擎坐標軸 webgl threejs cesium blender unity ue 左手坐標系、右手坐標系、坐標軸方向

平臺 / 引擎坐標系類型Up&#xff08;上&#xff09;方向Forward&#xff08;前進&#xff09;方向前進方向依據說明Unity左手坐標系YZtransform.forward 是 Z 軸正方向&#xff0c;默認攝像機朝 Z 看。Unreal Engine左手坐標系ZXUE 的角色面朝 X&#xff0c;默認使用 GetActor…

Cold Diffusion: Inverting Arbitrary Image Transforms Without Noise論文閱讀

冷擴散&#xff1a;無需噪聲的任意圖像變換反轉 摘要 標準擴散模型通常涉及兩個核心步驟&#xff1a;圖像降質 &#xff08;添加高斯噪聲&#xff09;和圖像恢復 &#xff08;去噪操作&#xff09;。本文發現&#xff0c;擴散模型的生成能力并不強烈依賴于噪聲的選擇&#xf…

Java并發編程核心組件簡單了解

一、Lock體系 1. ReentrantLock&#xff08;可重入鎖&#xff09; Lock lock new ReentrantLock(); lock.lock(); try {// 臨界區代碼 } finally {lock.unlock(); }特點&#xff1a;可重入、支持公平/非公平策略優勢&#xff1a;可中斷鎖獲取、定時鎖等待使用場景&#xff1…

第二個五年計劃!

下一階段&#xff01;5年后&#xff01;33歲&#xff01;體重維持在125斤內&#xff01;腰圍74&#xff01; 健康目標&#xff1a; 體檢指標正常&#xff0c;結節保持較小甚至變小&#xff01; 工作目標&#xff1a; 每年至少在一次考評里拿A&#xff08;最高S&#xff0c;A我理…

Redis(三) - 使用Java操作Redis詳解

文章目錄 前言一、創建項目二、導入依賴三、鍵操作四、字符串操作五、列表操作六、集合操作七、哈希表操作八、有序集合操作九、完整代碼1. 完整代碼2. 項目下載 前言 本文主要介紹如何使用 Java 操作 Redis 數據庫&#xff0c;涵蓋項目創建、依賴導入及 Redis 各數據類型&…

【Folium】使用離線地圖

文章目錄 相關文獻離線地圖下載Folium 使用離線地圖 相關文獻 Folium — Folium 0.19.5 documentationOffline Map Maker 離線地圖下載 我們使用 Offline Map Maker 進行地圖下載。 特別注意&#xff1a;Folium 默認支持 WGS84 坐標系&#xff0c;建議下載 WGS84 坐標系的地…

DeepSearch:字節新一代 DeerFlow 框架

項目地址&#xff1a;https://github.com/bytedance/deer-flow/ 【全新的 Multi-Agent 架構設計】獨家設計的 Research Team 機制&#xff0c;支持多輪對話、多輪決策和多輪任務執行。與 LangChain 原版 Supervisor 相比&#xff0c;顯著減少 Tokens 消耗和 API 調用次數&#…

Qt—用SQLite實現簡單的注冊登錄界面

1.實現目標 本次實現通過SQLite制作一個簡易的登錄窗口&#xff0c;當點擊注冊按鈕時&#xff0c;登錄窗口會消失&#xff0c;會出現一個新的注冊界面&#xff1b;完成注冊或退出注冊時&#xff0c;注冊窗口會消失&#xff0c;重新出現登錄窗口。注冊過的用戶信息會出現在SQLi…

day 18:零基礎學嵌入式之數據結構——

一、基礎內容 1.數據結構&#xff1a;相互之間存在一種或多種特定關系的數據元素的集合。 2.邏輯結構 &#xff08;1&#xff09;集合&#xff0c;所有數據在同一個集合中&#xff0c;關系平等。 &#xff08;2&#xff09;線性&#xff0c;數據和數據之間是一對一的關系 &am…

【SSL證書系列】客戶端如何驗證https網站服務器發的證書是否由受信任的根證書簽發機構簽發

客戶端驗證HTTPS網站證書是否由受信任的根證書頒發機構&#xff08;CA&#xff09;簽發&#xff0c;是一個多步驟的過程&#xff0c;涉及證書鏈驗證、信任錨&#xff08;Trust Anchor&#xff09;檢查、域名匹配和吊銷狀態驗證等。以下是詳細的驗證流程&#xff1a; 1. 證書鏈的…

iOS即時通信的技術要點

iOS即時通信開發的關鍵技術要點總結&#xff1a; 一、通訊協議選擇 Socket通信 基礎實現&#xff1a;使用原生BSD Socket或CFNetwork框架&#xff08;復雜&#xff09;&#xff0c;推薦第三方庫如CocoaAsyncSocket&#xff08;封裝GCDAsyncSocket&#xff09;&#xff0c;簡化T…