LiteOS雙向鏈表使用詳解

      網友投稿 840 2025-03-31

      官方開放文檔中關于雙向鏈表的介紹比較簡單,并沒有告訴大家到底怎么在自己的數據結構中使用鏈表。其實也比較簡單,時間緊的朋友可以直接看第二部分。


      一、雙向鏈表簡介

      雙向鏈表是指含有往前和往后兩個方向的鏈表,即每個結點中除存放下一個節點指針外,還增加一個指向其前一個節點的指針。其頭指針head是唯一確定的。從雙向鏈表的任意一個節點開始,都可以很方便的訪問它的前驅和后繼節點。如下圖所示:

      LiteOS雙向鏈接跟linux的內核鏈接原理一樣。LiteOS定義了雙向鏈表基本數據結構,并提供了相關的函數和宏定義來操作鏈表,用戶可以添加、刪除節點,遍歷節點等。

      LiteOS雙向鏈表數據結構定義如下,包含了兩個指針,分別指向前驅和后繼節點。這是個最基本的數據結構,僅包含有雙向鏈表。

      typedef?struct?LOS_DL_LIST { ????struct?LOS_DL_LIST?*pstPrev;????/**

      LiteOS雙向鏈表操作函數:

      VOID?LOS_ListInit(LOS_DL_LIST?*pstList) #define?LOS_DL_LIST_FIRST(pstObject)?((pstObject)->pstNext) VOID?LOS_ListAdd(LOS_DL_LIST?*pstList,?LOS_DL_LIST?*pstNode) VOID?LOS_ListTailInsert(LOS_DL_LIST?*pstList,?LOS_DL_LIST?*pstNode) VOID?LOS_ListDelete(LOS_DL_LIST?*pstNode) BOOL?LOS_ListEmpty(LOS_DL_LIST?*pstNode)?//return?(BOOL)(pstNode->pstNext?==?pstNode); //取得鏈表所在結構體地址,即根據鏈表節點的地址獲取用戶結構體地址. //item:?鏈表節點地址.用戶結構體中定義的鏈表成員的地址 //type:?用戶結構體名稱 //member:鏈表在用戶結構體中的成員名稱 #define?LOS_DL_LIST_ENTRY(item,?type,?member)?\ ????((type?*)((char?*)item?-?LOS_OFF_SET_OF(type,?member)))?\ //遍歷用戶結構體?for循環 //item:用戶結構體指針。需用戶在外定義好。 //list:?鏈表首地址 //type:?用戶結構體名稱 //member:?鏈表在用戶結構體中的成員名稱 #define?LOS_DL_LIST_FOR_EACH_ENTRY(item,?list,?type,?member)?\ ????for?(item?=?LOS_DL_LIST_ENTRY((list)->pstNext,?type,?member);?\ ????????&item->member?!=?(list);?\ ????????item?=?LOS_DL_LIST_ENTRY(item->member.pstNext,?type,?member))??? //遍歷用戶結構體,可刪除節點??for循環 //item:用戶結構體指針。需用戶在外定義好。 //next:?用戶結構體指針,指向item的下一個節點.?需用戶在外定義該變量。 //list:?鏈表首地址 //type:?用戶結構體名稱 //member:?鏈表在用戶結構體中的成員名稱???????? #define?LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item,?next,?list,?type,?member)????????????\ ????for?(item?=?LOS_DL_LIST_ENTRY((list)->pstNext,?type,?member),?\ ????????next?=?LOS_DL_LIST_ENTRY(item->member.pstNext,?type,?member);?\ ????????&item->member?!=?(list);?\ ????????item?=?next,?next?=?LOS_DL_LIST_ENTRY(item->member.pstNext,?type,?member))???? //遍歷雙向鏈表,不可有刪除節點.僅遍歷鏈表節點(不包括用戶結構體內容) //item:?鏈表指針,?需用戶定義好該變量 //list:?鏈表頭 #define?LOS_DL_LIST_FOR_EACH(item,?list)???\ ????for?((item)?=?(list)->pstNext;?\ ????????(item)?!=?(list);?\ ????????(item)?=?(item)->pstNext)???????? //安全遍歷雙向鏈表,可刪除節點.僅遍歷鏈表節點(不包括用戶結構體內容) //item:?鏈表指針,?需用戶定義好該變量 //next:?鏈表指針,?指向item下一個節點.需用戶定義好該變量 //list:?鏈表頭 #define?LOS_DL_LIST_FOR_EACH_SAFE(item,?next,?list)?\ ????for?(item?=?(list)->pstNext,?next?=?item->pstNext;?item?!=?(list);?\ ????????item?=?next,?next?=?item->pstNext)??? //?定義一個雙向鏈表節點并初始化,可用于初始化一個鏈表頭.變量名為list #define?LOS_DL_LIST_HEAD(list)?\ ????????????LOS_DL_LIST?list?=?{?&(list),?&(list)?}

      二、鏈表的使用

      LiteOS 內核定義的雙向鏈表跟Linux內核鏈表思想一致,它僅僅包含了兩個指針類型的變量。

      用戶使用雙向鏈表時,要將雙向鏈表加入自己的數據結構中。即定義一個結構體,成員包括用戶需要用到的數據類型,最后,在結構體中加入內核雙向鏈表數據類型,使之成為結構體的成員。

      如代碼所示,定義用戶結構體,包含雙向鏈表成員:

      typedef?struct { ????UINT16??????????member1;??//用戶數據????????? ????UINT16??????????member2;??//用戶數據據???????????????????? ????LOS_DL_LIST?????mList;????//雙向鏈表??? }?User_Data_t;

      LiteOS雙向鏈表使用詳解

      基本原理是:利用雙向鏈表,將用戶結構體中定義好的鏈表成員變量都鏈接起來;鏈表節點在用戶結構體中的偏移地址是固定的,根據鏈表節點的地址,減去偏移地址,就能得到用戶結構體變量的起始地址了。LiteOS中根據鏈表地址獲取用戶節點地址的宏定義是:

      //取得鏈表所在結構體地址,即根據鏈表節點的地址獲取用戶結構體地址. //item:?鏈表節點地址.用戶結構體中定義的鏈表成員的地址 //type:?用戶結構體名稱 //member:鏈表在用戶結構體中的成員名稱 #define?LOS_DL_LIST_ENTRY(item,?type,?member)?\ ????((type?*)((char?*)item?-?LOS_OFF_SET_OF(type,?member)))?\

      如下圖所示,利用鏈表將用戶節點中的鏈表成員鏈接起來

      示例代碼如下:

      User_Data_t??data1,data2,data3;?//定義用戶變量 LOS_DL_LIST??gHeader;???//定義鏈表頭 data1.member1?=?1;data2.member1?=?2;data3.member1?=?3;//初始化用戶數據 LOS_ListInit(&gHeader);??//初始化鏈表 LOS_ListTailInsert(&gHeader,&data1.mList);//將data1添加到鏈表尾部 LOS_ListTailInsert(&gHeader,&data2.mList);//將data2添加到鏈表尾部,即data1之后 LOS_ListTailInsert(&gHeader,&data3.mList);//將data3添加到鏈表尾部,即data2之后 //從鏈表中取數據? LOS_DL_LIST?*node; User_Data_t??*pData; node?=?LOS_DL_LIST_FIRST(&gHeader);?//獲取鏈表第一個節點.node指向data1.mList //根據node取得data1的地址 pData?=?LOS_DL_LIST_ENTRY(node,User_Data_t,mList); printf("data1.member1?is?%d!\r\n",pData->member1); //遍歷鏈表 LOS_DL_LIST_FOR_EACH_ENTRY(pData,&gHeader,User_Data_t,mList) { ????printf("data?member1?is?%d!\r\n",pData->member1); }

      軟件開發

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:wps怎么移動整頁(wps怎樣移動一整頁)
      下一篇:商城版低代碼開發平臺是什么(商城版低代碼開發平臺是什么軟件)
      相關文章
      亚洲成a人片在线网站| 亚洲熟妇色自偷自拍另类| 2020国产精品亚洲综合网| 亚洲AV区无码字幕中文色| 亚洲女初尝黑人巨高清| 国产精品亚洲w码日韩中文| 亚洲人成网站在线观看青青| www国产亚洲精品久久久| 成人亚洲网站www在线观看 | 亚洲伊人tv综合网色| 日韩精品亚洲人成在线观看| 久久久亚洲欧洲日产国码aⅴ| 亚洲AV永久无码精品| 亚洲人成网址在线观看| 亚洲国产精品国自产电影| 亚洲午夜视频在线观看| 亚洲日韩中文字幕| 亚洲人成人77777在线播放| 国产成人精品日本亚洲18图| 中文有码亚洲制服av片| 亚洲人成无码网站在线观看| 亚洲AV无码成人精品区日韩| 国内成人精品亚洲日本语音| 亚洲国产日韩成人综合天堂| 亚洲中久无码永久在线观看同| 日本亚洲视频在线| 亚洲最新永久在线观看| 亚洲最新中文字幕| 中文有码亚洲制服av片| 精品亚洲成A人在线观看青青| 亚洲精品456播放| 亚洲精品自在在线观看| 亚洲精品人成在线观看| 亚洲妓女综合网99| 亚洲欧美一区二区三区日产| 亚洲AV无码一区二区三区鸳鸯影院| 亚洲精品国产日韩无码AV永久免费网| 国产亚洲自拍一区| 久久久亚洲精品国产| 亚洲黄色免费在线观看| 亚洲狠狠成人综合网|