//已知链表地址,怎么得到链表所属的结构体的地址.
pOpenHead = CONTAINING_RECORD( pEntry, HW_OPEN_INFO, llist);
//链表类型为llist,所属上层结构体为HW_OPEN_INFO,pEntry就是已分配内存的链表的地址
/* #define CONTAINING_RECORD(address, type, field) ((type *)( \ (LPBYTE)(address) - \ (LPBYTE)(&((type *)0)->field))) */
/* typedef struct __HW_OPEN_INFO { PHW_INDEP_INFO pSerialHead; // @field Pointer back to our HW_INDEP_INFO DWORD AccessCode; // @field What permissions was this opened with DWORD ShareMode; // @field What Share Mode was this opened with DWORD StructUsers; // @field Count of threads currently using struct. COMM_EVENTS CommEvents; // @field Contains all info for serial event handling LIST_ENTRY llist; // @field Linked list of OPEN_INFOs } HW_OPEN_INFO, *PHW_OPEN_INFO; */
//链表怎么初始化和 插入的: 答链表头必须要用InitializeListHead初始化,要插入的节点不需要,
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY * Flink;
int a;
struct _LIST_ENTRY * Blink;
} LIST_ENTRY,*PLIST_ENTRY;
EX_ListHead是一个_LIST_ENTRY结构体变量,那么EX_ListHead.Flink和EX_ListHead.Flink->Blink代表什么?
答:EX_ListHead.Flink和代表一个_LIST_ENTRY类型的指针,这个指针站4个字节位于EX_ListHead变量的空间内,
EX_ListHead.Flink->Blink,如果令EX_ListHead.Flink=X, 那么EX_ListHead.Flink->Blink相当于X.Blink
//定义2个变量
LIST_ENTRY OpenList; // @field Head of linked list of OPEN_INFOs
LIST_ENTRY llist;
LIST_ENTRY llist2;
InitializeListHead( &OpenList );
InsertHeadList(&OpenList,&llist);
//他们2个关系如图
InsertHeadList(&OpenList,&llist2);
//他们3个关系如图:
附录:
#define InitializeListHead(ListHead) \ ((ListHead)->Flink = (ListHead)->Blink = (ListHead) ) #define IsListEmpty(ListHead) \ (( ((ListHead)->Flink == (ListHead)) ? TRUE : FALSE ) ) #define RemoveHeadList(ListHead) \ (ListHead)->Flink;\ {\ PLIST_ENTRY FirstEntry;\ FirstEntry = (ListHead)->Flink;\ FirstEntry->Flink->Blink = (ListHead);\ (ListHead)->Flink = FirstEntry->Flink;\ } #define RemoveEntryList(Entry) do {\ PLIST_ENTRY _EX_Entry;\ _EX_Entry = (Entry);\ _EX_Entry->Blink->Flink = _EX_Entry->Flink;\ _EX_Entry->Flink->Blink = _EX_Entry->Blink;\ } while(0); _inline PLIST_ENTRY RemoveTailList(PLIST_ENTRY ListHead) { PLIST_ENTRY _Tail_Entry; _Tail_Entry = ListHead->Blink; RemoveEntryList(_Tail_Entry); return _Tail_Entry; } #define InsertTailList(_ListHead,_Entry) do {\ PLIST_ENTRY _EX_ListHead = _ListHead; \ PLIST_ENTRY _EX_Blink = _EX_ListHead->Blink; \ (_Entry)->Flink = _EX_ListHead; \ (_Entry)->Blink = _EX_Blink; \ _EX_Blink->Flink = _Entry; \ _EX_ListHead->Blink = _Entry; \ } while(0); #define InsertHeadList(_ListHead,_Entry) do {\ PLIST_ENTRY _EX_ListHead = _ListHead; \ PLIST_ENTRY _EX_Flink = _EX_ListHead->Flink; \ (_Entry)->Flink = _EX_Flink; \ (_Entry)->Blink = _EX_ListHead; \ _EX_Flink->Blink = _Entry; \ _EX_ListHead->Flink = _Entry; \ } while (0);