⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 list.h

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 H
📖 第 1 页 / 共 2 页
字号:


/*
 * LIST.H
 */
/*------------------------------------------------------------------------
| Abstract data type LIST OF (*untyped*) object.
| Different lists can have different types of object in them
| Different items in a list can have different types of object in them.
| The price of this lack of typing is that you have a slightly more
| awkward syntax and you get no help from the compiler if you try to
| put the wrong type of data into the list.
|
| The list is implemented as a collection of items.  Within the item
| somewhere is the object.
|
| Objects are stored UNALIGNED within items.
|
| Use:
|
|   #include <list.h>
|   . . .
|   LIST MyList; (* or LIST liMyList for Hungarians *)
|   . . .
|   MyList = List_Create();
|   List_AddLast(MyList,&MyObject,sizeof(OBJECT));
|
| In the abstract a LIST is a list of objects.  The representation
| is a linked collection of items.  The manner of the linking is
| implementation dependent (as I write this it's linear but when you
| read it it might be a tree (See Knuth for why a tree)).
|
| A LIST is a "handle" for a list which may be thought of as a POINTER
| (whether it is really a pointer or not is implementation dependent)
| so that it can be copied at the risk of creating an alias. e.g.
|
|   L = List_Create();
|   L1 = L;             (* L and L1 are both healthy and empty *)
|   List_AddFirst(L, &elem, sizeof(elem));
|   (* L1 may also appear to have one object, there again it may be sick *)
|   L1 = L;               (* Now they both surely see the one element *)
|   List_Destroy(&L1);    (* L is almost certainly sick now too *)
|   L1 = List_Create();   (* All bets off as to what L is like now
|                            but L1 is empty and healthy
|                         *)
|
| If two handles compare equal then the lists must be equal, but
| unequal handles could address two similar lists i.e. the same list
| of objects held in two different LISTs of items (like pointers).
|
| A LIST can be transferred from one variable to another like this:
|
|   NewList = OldList;           (* copy the handle *)
|   OldList = List_Create();     (* kill the old alias *)
|
| and the Create statement can be omitted if OldList is never touched again.
|
| Items are identified by Cursors.  A cursor is the address of an object
| within an item in the list. i.e. it is the address of the piece of your
| data that you had inserted.  (It is probably NOT the address of the item).
| It is typed as pointer to void here, but you should declare it as a pointer
| to whatever sort of object you are putting in the LIST.
|
| The operations AddFirst, AddLast, AddAfter and AddBefore
| all copy elements by direct assignment.  If an element is itself
| a complex structure (say a tree) then this will only copy a pointer
| or an anchor block or whatever and give all the usual problems of
| aliases.  Clear will make the list empty, but will only free the
| storage that it can "see" directly.  SplitBefore or Split After may
| also perform a Clear operation.  To deal with fancy data structures
| use New rather than Add calls and copy the data yourself
|   e.g.  P = List_NewLast(MyList, sizeof(MyArray[14])*(23-14+1));
|         CopyArraySlice(P, MyArray, 14, 23);
|
| The operations NewFirst, NewLast, NewAfter, NewBefore, First and Last
| all return pointers to elements and thus allow you to do any copying.
| This is how you might copy a whole list of fancy structures:
|
|    void CopyFancyList(LIST * To, LIST From)
|             (* Assumes that To has been Created and is empty *)
|    { PELEMENT Cursor;
|      PELEMENT P;
|
|      List_TRAVERSE(From, Cursor);
|      { P = List_NewLast(To, sizeof(element) );
|        FancyCopy(P, Cursor);    (* Copy so that *Cursor==*P afterwords *)
|      }
|    }
 --------------------------------------------------------------------*/

  typedef struct item_tag FAR * LIST;
  typedef LIST FAR * PLIST;

  void APIENTRY List_Init(void);
  /* MUST BE CALLED BEFORE ANY OF THE OTHER FUNCTIONS. */

  void APIENTRY List_Dump(LPSTR Header, LIST lst);
  /* Dump the internals to current output stream -- debug only */

  void APIENTRY List_Show(LIST lst);
  /* Dump hex representation of handle to current out stream -- debug only */

  LIST APIENTRY List_Create(void);
  /* Create a list.  It will be initially empty */

  void APIENTRY List_Destroy(PLIST plst);
  /* Destroy *plst.  It does not need to be empty first.
  |  All storage directly in the list wil be freed.
  */

  void APIENTRY List_AddFirst(LIST lst, LPVOID pObject, UINT uLen);
  /* Add an item holding Object to the beginning of * plst */

  LPVOID APIENTRY List_NewFirst(LIST lst, UINT uLen);
  /* Return the address of the place for Len bytes of data in a new
  |  item at the start of *plst
  */

  void APIENTRY List_DeleteFirst(LIST lst);
  /* Delete the first item in lst.  Error if lst is empty */

  void APIENTRY List_AddLast(LIST lst, LPVOID pObject, UINT uLen);
  /* Add an item holding Object to the end of lst */

  LPVOID APIENTRY List_NewLast(LIST lst, UINT uLen);
  /* Return the address of the place for uLen bytes of data in a new
  |  item at the end of lst
  */

  void APIENTRY List_DeleteLast(LIST lst);
  /* Delete the last item in lst.  Error if lst is empty */

  void APIENTRY List_AddAfter( LIST lst
                    , LPVOID Curs
                    , LPVOID pObject
                    , UINT uLen
                    );
  /*--------------------------------------------------------------------
  | Add an item holding *pObject to lst immediately after Curs.
  | List_AddAfter(lst, NULL, pObject, Len) adds it to the start of the lst
   ---------------------------------------------------------------------*/

  LPVOID APIENTRY List_NewAfter(LIST lst, LPVOID Curs, UINT uLen);
  /*--------------------------------------------------------------------
  | Return the address of the place for uLen bytes of data in a new
  | item immediately after Curs.
  | List_NewAfter(Lst, NULL, uLen) returns a pointer
  | to space for uLen bytes in a new first element.
   ---------------------------------------------------------------------*/

  void APIENTRY List_AddBefore( LIST lst
                     , LPVOID Curs
                     , LPVOID pObject
                     , UINT uLen
                     );
  /*--------------------------------------------------------------------
  | Add an item holding Object to lst immediately before Curs.
  | List_AddBefore(Lst, NULL, Object, uLen) adds it to the end of the list
   ---------------------------------------------------------------------*/

  LPVOID APIENTRY List_NewBefore(LIST lst, LPVOID Curs, UINT uLen );
  /*--------------------------------------------------------------------
  | Return the address of the place for uLen bytes of data in a new
  | item immediately before Curs.
  | List_NewBefore(Lst, NULL, uLen) returns a pointer
  | to space for uLen bytes in a new last element.
   ---------------------------------------------------------------------*/

  void APIENTRY List_Delete(LPVOID Curs);
  /*------------------------------------------------------------------
  | Delete the item that Curs identifies.
  | This will be only a few (maybe as little as 3) machine instructions
  | quicker than DeleteAndNext or DeleteAndPrev but leaves Curs dangling.
  | It is therefore NOT usually to be preferred.
  | It may be useful when you have a function which returns an LPVOID
  | since the argument does not need to be a variable.
  |     Trivial example: List_Delete(List_First(L));
   -------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -