vxworks系统下列表的使用

来源:互联网 发布:java 替换jar 编辑:程序博客网 时间:2024/06/06 04:31

vxWorks系统对常用数据结构的实现比较少,但是提供了对双向链表的支持,其声明位于lstLib.h头文件中,主要定义了以下一些内容:

 

1、LIST类型

     LIST类型的定义如下:

[cpp] view plaincopy
  1. typedef struct   /* Header for a linked list. */  
  2. {  
  3.     NODE node;   /* Header list node */  
  4.     int count;   /* Number of nodes in list */  
  5. } LIST;  
  6.   
  7. /* lstLib实现文件中的部分内容 */  
  8. #define  HEAD     node.next  
  9. #define  TAIL     node.previous  

     LIST结构体属于是对整个链表的描述,它包括了链表的头指针、尾指针以及链表中节点的个数。其中,node的next指针是LIST的头指针(HEAD),node的previous指针是LIST的尾指针(TAIL),这在lstLib的实现中是通过宏来定义的,其定义如上边代码区下部:

定义LIST类型是使用链表的第一步,一般情况下都要以

    LIST myList;

的形式定义一个链表。

 

2、NODE类型

     其定义如下:

[cpp] view plaincopy
  1. typedef struct node /* Node of a linked list. */  
  2. {  
  3.     struct node *next;      /* Points at the next node in the list */  
  4.     struct node *previous;  /* Points at the previous node in the list */  
  5. } NODE;  
  6.   
  7. /* 定义自己的节点类型 */  
  8. typedef struct _MyNode  
  9. {  
  10.     NODE   ndptrs;     /* 第一个数据必须是NODE类型 */  
  11.     /* 节点数据部分定义,根据实际情况而定 */  
  12.     int    data;  
  13. } MyNode;  
  14.   
  15. /* 自定义类型的使用示例 */  
  16. LIST myList, *srcLst;  
  17. MyNode *node;  
  18. srcLst = &myList;  
  19. lstInit(srcLst);  
  20. ......  
  21. node = (MyNode *)malloc(sizeof(MyNode));  
  22. lstAdd(srcLst, (NODE *)node);  
  23. ......  

    NODE类型只是提供了对节点最基本的描述,一般情况下在自己的代码中是不能直接使用的,而是需要定义一个自己的节点数据类型,定义自己节点类型的时候,切记结构体的第一个位置必须是NODE类型的。这样,在程序中,创建节点的时候就创建一个MyNode类型的,而使用系统链表函数的时候,就把它强制转换成NODE类型,使用示例见上边代码最下部。

 

3、相关函数。

     函数的作用在此就不罗嗦了,后边有每个函数的实现,需要注意的是lstNth函数和lstExtract函数,lstNth函数中的序号应该是从1开始的,而不是0. lstExtract函数分出来的子列表时即包括startNode,又包括endNode的。另外需要注意的就是开始使用链表前先使用lstInit函数初始化,使用过程中删除的节点记得释放其空间(如果是malloc分配的话),使用完链表之后使用lstFree释放链表空间。

 

 

所以,使用链表的一般步骤是:

   首先定义自己的节点类型,定义一个LIST数据。

   使用lstInit对链表进行初始化

   使用系统提供的函数对链表进行操作,使用的过程中,用到自定义节点类型时记得类型转换,删除节点时记得释放空间。

   使用完链表,释放链表空间。

 

lstLib.c文件源码

[cpp] view plaincopy
  1. /* lstLib.c - doubly linked list subroutine library */  
  2.   
  3. /* Copyright 1984-2001 Wind River Systems, Inc. */  
  4. #include "copyright_wrs.h"  
  5.   
  6. /* 
  7. modification history 
  8. -------------------- 
  9. 02a,19sep01,pcm  added lstLibInit () to bring module into image (SPR 20698) 
  10. 01z,05oct98,jmp  doc: cleanup. 
  11. 01y,14oct95,jdi  doc: fixed typo in lstNth(). 
  12. 01x,13feb95,jdi  doc format change. 
  13. 01w,20jan93,jdi  documentation cleanup for 5.1. 
  14. 01v,09jul92,hdn  put an optimized lstGet() 
  15. 01u,26may92,rrr  the tree shuffle 
  16. 01t,25nov91,rrr  cleanup of some ansi warnings. 
  17. 01s,04oct91,rrr  passed through the ansification filter 
  18.                   -changed functions to ansi style 
  19.           -changed VOID to void 
  20.           -changed copyright notice 
  21. 01r,30apr91,jdi  documentation tweaks. 
  22. 01q,05apr91,jdi  documentation -- removed header parens and x-ref numbers; 
  23.          doc review by dnw. 
  24. 01p,11feb91,jaa  documentation cleanup. 
  25. 01o,05nov87,jlf  documentation 
  26. 01n,02apr87,ecs  hushed lint in lstFree. 
  27. 01m,25mar87,jlf  documentation 
  28. 01l,21dec86,dnw  changed to not get include files from default directories. 
  29. 01k,01jul86,jlf  documentation. 
  30. 01j,21may86,llk  added lstFree and lstNStep. 
  31. 01i,09apr86,rdc  added lstFind. 
  32. 01h,20jul85,jlf  documentation. 
  33. 01g,19sep84,jlf  fixed spacing in comments by adding .ne's. 
  34. 01f,08sep84,jlf  added comments and copyright notice. 
  35. 01e,29jun84,dnw  added lstConcat and lstExtract. 
  36. 01d,03jun84,dnw  added lstFirst, lstLast. 
  37.          changed list.{head,tail} to list.node.{next,previous}. 
  38.          cleaned up comments, etc. 
  39. 01c,07may84,ecs  added lstNext, lstPrevious, and lstCount. 
  40. 01b,09jun83,ecs  modified the documentation 
  41. 01a,06aug82,dnw  created from old singly-linked-list lib which is now "slllb". 
  42. */  
  43.   
  44.   
  45. /* 
  46. DESCRIPTION 
  47. This subroutine library supports the creation and maintenance of a 
  48. doubly linked list.  The user supplies a list descriptor (type LIST) 
  49. that will contain pointers to the first and last nodes in the list, 
  50. and a count of the number of nodes in the list.  The nodes in the 
  51. list can be any user-defined structure, but they must reserve space 
  52. for two pointers as their first elements.  Both the forward and 
  53. backward chains are terminated with a NULL pointer. 
  54.  
  55. The linked-list library simply manipulates the linked-list data structures; 
  56. no kernel functions are invoked.  In particular, linked lists by themselves 
  57. provide no task synchronization or mutual exclusion.  If multiple tasks will 
  58. access a single linked list, that list must be guarded with some 
  59. mutual-exclusion mechanism (e.g., a mutual-exclusion semaphore). 
  60.  
  61. NON-EMPTY LIST: 
  62. .CS 
  63.    ---------             --------          -------- 
  64.    | head--------------->| next----------->| next--------- 
  65.    |       |             |      |          |      |      | 
  66.    |       |       ------- prev |<---------- prev |      | 
  67.    |       |       |     |      |          |      |      | 
  68.    | tail------    |     | ...  |    ----->| ...  |      | 
  69.    |       |  |    v                 |                   v 
  70.    |count=2|  |  -----               |                 ----- 
  71.    ---------  |   ---                |                  --- 
  72.               |    -                 |                   - 
  73.               |                      | 
  74.               ------------------------ 
  75. .CE 
  76.  
  77. EMPTY LIST: 
  78. .CS 
  79.     ----------- 
  80.         |  head------------------ 
  81.         |         |             | 
  82.         |  tail----------       | 
  83.         |         |     |       v 
  84.         | count=0 |   -----   ----- 
  85.         -----------    ---     --- 
  86.                         -   - 
  87. .CE 
  88.  
  89. INCLUDE FILES: lstLib.h 
  90. */  
  91.   
  92.   
  93. /* LINTLIBRARY */  
  94.   
  95. #include "vxWorks.h"  
  96. #include "lstLib.h"  
  97. #include "stdlib.h"  
  98.   
  99. #define HEAD    node.next       /* first node in list */  
  100. #define TAIL    node.previous       /* last node in list */  
  101.   
  102. /********************************************************************* 
  103. * 
  104. * lstLibInit - initializes lstLib module 
  105. * 
  106. * This routine pulls lstLib into the vxWorks image. 
  107. * 
  108. * RETURNS: N/A 
  109. */  
  110. void lstLibInit (void)  
  111.     {  
  112.     return;  
  113.     }  
  114.   
  115. /********************************************************************* 
  116. * 
  117. * lstInit - initialize a list descriptor 
  118. * 
  119. * This routine initializes a specified list to an empty list. 
  120. * 
  121. * RETURNS: N/A 
  122. */  
  123.   
  124. void lstInit  
  125.     (  
  126.     FAST LIST *pList     /* ptr to list descriptor to be initialized */  
  127.     )  
  128.     {  
  129.     pList->HEAD   = NULL;  
  130.     pList->TAIL  = NULL;  
  131.     pList->count = 0;  
  132.     }  
  133. /************************************************************************* 
  134. * 
  135. * lstAdd - add a node to the end of a list 
  136. * 
  137. * This routine adds a specified node to the end of a specified list. 
  138. * 
  139. * RETURNS: N/A 
  140. */  
  141.   
  142. void lstAdd  
  143.     (  
  144.     LIST *pList,        /* pointer to list descriptor */  
  145.     NODE *pNode         /* pointer to node to be added */  
  146.     )  
  147.     {  
  148.     lstInsert (pList, pList->TAIL, pNode);  
  149.     }  
  150. /************************************************************************** 
  151. * 
  152. * lstConcat - concatenate two lists 
  153. * 
  154. * This routine concatenates the second list to the end of the first list. 
  155. * The second list is left empty.  Either list (or both) can be 
  156. * empty at the beginning of the operation. 
  157. * 
  158. * RETURNS: N/A 
  159. */  
  160.   
  161. void lstConcat  
  162.     (  
  163.     FAST LIST *pDstList,        /* destination list */  
  164.     FAST LIST *pAddList         /* list to be added to dstList */  
  165.     )  
  166.     {  
  167.     if (pAddList->count == 0)        /* nothing to do if AddList is empty */  
  168.     return;  
  169.   
  170.     if (pDstList->count == 0)  
  171.     *pDstList = *pAddList;  
  172.     else  
  173.     {  
  174.     /* both lists non-empty; update DstList pointers */  
  175.   
  176.     pDstList->TAIL->next     = pAddList->HEAD;  
  177.     pAddList->HEAD->previous = pDstList->TAIL;  
  178.     pDstList->TAIL           = pAddList->TAIL;  
  179.   
  180.     pDstList->count += pAddList->count;  
  181.     }  
  182.   
  183.     /* make AddList empty */  
  184.   
  185.     lstInit (pAddList);  
  186.     }  
  187. /************************************************************************** 
  188. * 
  189. * lstCount - report the number of nodes in a list 
  190. * 
  191. * This routine returns the number of nodes in a specified list. 
  192. * 
  193. * RETURNS: 
  194. * The number of nodes in the list. 
  195. */  
  196.   
  197. int lstCount  
  198.     (  
  199.     LIST *pList         /* pointer to list descriptor */  
  200.     )  
  201.     {  
  202.     return (pList->count);  
  203.     }  
  204. /************************************************************************** 
  205. * 
  206. * lstDelete - delete a specified node from a list 
  207. * 
  208. * This routine deletes a specified node from a specified list. 
  209. * 
  210. * RETURNS: N/A 
  211. */  
  212.   
  213. void lstDelete  
  214.     (  
  215.     FAST LIST *pList,   /* pointer to list descriptor */  
  216.     FAST NODE *pNode    /* pointer to node to be deleted */  
  217.     )  
  218.     {  
  219.     if (pNode->previous == NULL)  
  220.     pList->HEAD = pNode->next;  
  221.     else  
  222.     pNode->previous->next = pNode->next;  
  223.   
  224.     if (pNode->next == NULL)  
  225.     pList->TAIL = pNode->previous;  
  226.     else  
  227.     pNode->next->previous = pNode->previous;  
  228.   
  229.     /* update node count */  
  230.   
  231.     pList->count--;  
  232.     }  
  233. /************************************************************************ 
  234. * 
  235. * lstExtract - extract a sublist from a list 
  236. * 
  237. * This routine extracts the sublist that starts with <pStartNode> and ends 
  238. * with <pEndNode> from a source list.  It places the extracted list in 
  239. * <pDstList>. 
  240. * 
  241. * RETURNS: N/A 
  242. */  
  243.   
  244. void lstExtract  
  245.     (  
  246.     FAST LIST *pSrcList,      /* pointer to source list */  
  247.     FAST NODE *pStartNode,    /* first node in sublist to be extracted */  
  248.     FAST NODE *pEndNode,      /* last node in sublist to be extracted */  
  249.     FAST LIST *pDstList       /* ptr to list where to put extracted list */  
  250.     )  
  251.     {  
  252.     FAST int i;  
  253.     FAST NODE *pNode;  
  254.   
  255.     /* fix pointers in original list */  
  256.   
  257.     if (pStartNode->previous == NULL)  
  258.     pSrcList->HEAD = pEndNode->next;  
  259.     else  
  260.     pStartNode->previous->next = pEndNode->next;  
  261.   
  262.     if (pEndNode->next == NULL)  
  263.     pSrcList->TAIL = pStartNode->previous;  
  264.     else  
  265.     pEndNode->next->previous = pStartNode->previous;  
  266.   
  267.   
  268.     /* fix pointers in extracted list */  
  269.   
  270.     pDstList->HEAD = pStartNode;  
  271.     pDstList->TAIL = pEndNode;  
  272.   
  273.     pStartNode->previous = NULL;  
  274.     pEndNode->next       = NULL;  
  275.   
  276.   
  277.     /* count number of nodes in extracted list and update counts in lists */  
  278.   
  279.     i = 0;  
  280.   
  281.     for (pNode = pStartNode; pNode != NULL; pNode = pNode->next)  
  282.     i++;  
  283.   
  284.     pSrcList->count -= i;  
  285.     pDstList->count = i;  
  286.     }  
  287. /************************************************************************ 
  288. * 
  289. * lstFirst - find first node in list 
  290. * 
  291. * This routine finds the first node in a linked list. 
  292. * 
  293. * RETURNS 
  294. * A pointer to the first node in a list, or 
  295. * NULL if the list is empty. 
  296. */  
  297.   
  298. NODE *lstFirst  
  299.     (  
  300.     LIST *pList         /* pointer to list descriptor */  
  301.     )  
  302.     {  
  303.     return (pList->HEAD);  
  304.     }  
  305. /************************************************************************ 
  306. * 
  307. * lstGet - delete and return the first node from a list 
  308. * 
  309. * This routine gets the first node from a specified list, deletes the node 
  310. * from the list, and returns a pointer to the node gotten. 
  311. * 
  312. * RETURNS 
  313. * A pointer to the node gotten, or 
  314. * NULL if the list is empty. 
  315. */  
  316.   
  317. NODE *lstGet  
  318.     (  
  319.     FAST LIST *pList    /* ptr to list from which to get node */  
  320.     )  
  321.     {  
  322.     FAST NODE *pNode = pList->HEAD;  
  323.   
  324.     if (pNode != NULL)                      /* is list empty? */  
  325.     {  
  326.     pList->HEAD = pNode->next;          /* make next node be 1st */  
  327.   
  328.     if (pNode->next == NULL)            /* is there any next node? */  
  329.         pList->TAIL = NULL;             /*   no - list is empty */  
  330.     else  
  331.         pNode->next->previous = NULL;   /*   yes - make it 1st node */  
  332.   
  333.     pList->count--;                     /* update node count */  
  334.     }  
  335.   
  336.     return (pNode);  
  337.     }  
  338. /************************************************************************ 
  339. * 
  340. * lstInsert - insert a node in a list after a specified node 
  341. * 
  342. * This routine inserts a specified node in a specified list. 
  343. * The new node is placed following the list node <pPrev>. 
  344. * If <pPrev> is NULL, the node is inserted at the head of the list. 
  345. * 
  346. * RETURNS: N/A 
  347. */  
  348.   
  349. void lstInsert  
  350.     (  
  351.     FAST LIST *pList,   /* pointer to list descriptor */  
  352.     FAST NODE *pPrev,   /* pointer to node after which to insert */  
  353.     FAST NODE *pNode    /* pointer to node to be inserted */  
  354.     )  
  355.     {  
  356.     FAST NODE *pNext;  
  357.   
  358.     if (pPrev == NULL)  
  359.     {               /* new node is to be first in list */  
  360.     pNext = pList->HEAD;  
  361.     pList->HEAD = pNode;  
  362.     }  
  363.     else  
  364.     {               /* make prev node point fwd to new */  
  365.     pNext = pPrev->next;  
  366.     pPrev->next = pNode;  
  367.     }  
  368.   
  369.     if (pNext == NULL)  
  370.     pList->TAIL = pNode;     /* new node is to be last in list */  
  371.     else  
  372.     pNext->previous = pNode; /* make next node point back to new */  
  373.   
  374.   
  375.     /* set pointers in new node, and update node count */  
  376.   
  377.     pNode->next      = pNext;  
  378.     pNode->previous  = pPrev;  
  379.   
  380.     pList->count++;  
  381.     }  
  382. /************************************************************************ 
  383. * 
  384. * lstLast - find the last node in a list 
  385. * 
  386. * This routine finds the last node in a list. 
  387. * 
  388. * RETURNS 
  389. * A pointer to the last node in the list, or 
  390. * NULL if the list is empty. 
  391. */  
  392.   
  393. NODE *lstLast  
  394.     (  
  395.     LIST *pList         /* pointer to list descriptor */  
  396.     )  
  397.     {  
  398.     return (pList->TAIL);  
  399.     }  
  400. /************************************************************************ 
  401. * 
  402. * lstNext - find the next node in a list 
  403. * 
  404. * This routine locates the node immediately following a specified node. 
  405. * 
  406. * RETURNS: 
  407. * A pointer to the next node in the list, or 
  408. * NULL if there is no next node. 
  409. */  
  410.   
  411. NODE *lstNext  
  412.     (  
  413.     NODE *pNode         /* ptr to node whose successor is to be found */  
  414.     )  
  415.     {  
  416.     return (pNode->next);  
  417.     }  
  418. /************************************************************************ 
  419. * 
  420. * lstNth - find the Nth node in a list 
  421. * 
  422. * This routine returns a pointer to the node specified by a number <nodenum> 
  423. * where the first node in the list is numbered 1. 
  424. * Note that the search is optimized by searching forward from the beginning 
  425. * if the node is closer to the head, and searching back from the end 
  426. * if it is closer to the tail. 
  427. * 
  428. * RETURNS: 
  429. * A pointer to the Nth node, or 
  430. * NULL if there is no Nth node. 
  431. */  
  432.   
  433. NODE *lstNth  
  434.     (  
  435.     FAST LIST *pList,           /* pointer to list descriptor */  
  436.     FAST int nodenum            /* number of node to be found */  
  437.     )  
  438.     {  
  439.     FAST NODE *pNode;  
  440.   
  441.     /* verify node number is in list */  
  442.   
  443.     if ((nodenum < 1) || (nodenum > pList->count))  
  444.     return (NULL);  
  445.   
  446.   
  447.     /* if nodenum is less than half way, look forward from beginning; 
  448.     otherwise look back from end */  
  449.   
  450.     if (nodenum < (pList->count >> 1))  
  451.     {  
  452.     pNode = pList->HEAD;  
  453.   
  454.     while (--nodenum > 0)  
  455.         pNode = pNode->next;  
  456.     }  
  457.   
  458.     else  
  459.     {  
  460.     nodenum -= pList->count;  
  461.     pNode = pList->TAIL;  
  462.   
  463.     while (nodenum++ < 0)  
  464.         pNode = pNode->previous;  
  465.     }  
  466.   
  467.     return (pNode);  
  468.     }  
  469. /************************************************************************ 
  470. * 
  471. * lstPrevious - find the previous node in a list 
  472. * 
  473. * This routine locates the node immediately preceding the node pointed to  
  474. * by <pNode>. 
  475. * 
  476. * RETURNS: 
  477. * A pointer to the previous node in the list, or 
  478. * NULL if there is no previous node. 
  479. */  
  480.   
  481. NODE *lstPrevious  
  482.     (  
  483.     NODE *pNode         /* ptr to node whose predecessor is to be found */  
  484.     )  
  485.     {  
  486.     return (pNode->previous);  
  487.     }  
  488. /************************************************************************ 
  489. * 
  490. * lstNStep - find a list node <nStep> steps away from a specified node 
  491. * 
  492. * This routine locates the node <nStep> steps away in either direction from  
  493. * a specified node.  If <nStep> is positive, it steps toward the tail.  If 
  494. * <nStep> is negative, it steps toward the head.  If the number of steps is 
  495. * out of range, NULL is returned. 
  496. * 
  497. * RETURNS: 
  498. * A pointer to the node <nStep> steps away, or 
  499. * NULL if the node is out of range. 
  500. */  
  501.   
  502. NODE *lstNStep  
  503.     (  
  504.     FAST NODE *pNode,           /* the known node */  
  505.     int nStep                   /* number of steps away to find */  
  506.     )  
  507.     {  
  508.     int i;  
  509.   
  510.     for (i = 0; i < abs (nStep); i++)  
  511.     {  
  512.     if (nStep < 0)  
  513.         pNode = pNode->previous;  
  514.     else if (nStep > 0)  
  515.         pNode = pNode->next;  
  516.     if (pNode == NULL)  
  517.         break;  
  518.     }  
  519.     return (pNode);  
  520.     }  
  521.   
  522. /************************************************************************ 
  523. * 
  524. * lstFind - find a node in a list 
  525. * 
  526. * This routine returns the node number of a specified node (the  
  527. * first node is 1). 
  528. * 
  529. * RETURNS: 
  530. * The node number, or 
  531. * ERROR if the node is not found. 
  532. */  
  533.   
  534. int lstFind  
  535.     (  
  536.     LIST *pList,                /* list in which to search */  
  537.     FAST NODE *pNode            /* pointer to node to search for */  
  538.     )  
  539.     {  
  540.   
  541.     FAST NODE *pNextNode;  
  542.     FAST int index = 1;  
  543.   
  544.     pNextNode = lstFirst (pList);  
  545.   
  546.     while ((pNextNode != NULL) && (pNextNode != pNode))  
  547.     {  
  548.     index++;  
  549.     pNextNode = lstNext (pNextNode);  
  550.     }  
  551.   
  552.     if (pNextNode == NULL)  
  553.     return (ERROR);  
  554.     else  
  555.     return (index);  
  556.     }  
  557.   
  558. /************************************************************************ 
  559. * 
  560. * lstFree - free up a list 
  561. * 
  562. * This routine turns any list into an empty list. 
  563. * It also frees up memory used for nodes. 
  564. * 
  565. * RETURNS: N/A 
  566. * 
  567. * SEE ALSO: free() 
  568. */  
  569.   
  570. void lstFree  
  571.     (  
  572.     LIST *pList         /* list for which to free all nodes */  
  573.     )  
  574.     {  
  575.     NODE *p1, *p2;  
  576.   
  577.     if (pList->count > 0)  
  578.     {  
  579.     p1 = pList->HEAD;  
  580.     while (p1 != NULL)  
  581.         {  
  582.         p2 = p1->next;  
  583.         free ((char *)p1);  
  584.         p1 = p2;  
  585.         }  
  586.     pList->count = 0;  
  587.     pList->HEAD = pList->TAIL = NULL;  
  588.     }  
  589.     }