user-0 提问: 问一个关于数据结构的问题

回复:
user: user-0
content: 引用 1 楼 user-7 的回复:想要 链表 跟 数据 解耦  ，  又不想用模板 ，  那么这是一个 插入式的双链表  感谢思路 找到能用的了 以后在研究

user: user-1
content: 引用 6 楼 u013592079 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 照Linux内核的list抄一遍也不让？！  包含了其他的头文件啊 [/quote] 只要把内核源码里的list.h文件拷贝到你的代码目录下，注释掉里面所有的include行，然后把 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({      \   const typeof( ((type *)0)->member ) *__mptr = (ptr);  \   (type *)( (char *)__mptr - offsetof(type,member) );})  # define POISON_POINTER_DELTA 0 #define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA) #define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)  这几个宏放在list.h文件前面就能用了。  另外还可以用零长度数组，在分配节点内存时把数据结构的长度放在结尾。 struct head {     struct head * next;     char data[0]; }; struct mydata {     int x;     unsigned long long y;     double z; }; ... struct head * node = (struct head *)malloc(sizeof(struct head)+sizeof(struct mydata)); ... struct mydata * data = (struct mydata *)node->data; printf("x = %d, y=%llu, z=%f\n", data->x, data->y, data->z); 当然也可以象8楼所说的用void * data指向分配数据的内存。 另外我还试过： struct node {     struct head * next; }; struct list {     struct node * head;     struct node * tail;     int size; } struct mydata {     struct node link; //只要保证链表节点是数据结构的第一个项，那么节点的地址就是就是数据结构的地址。     int x;     unsigned long long y;     double z; };  ... struct node * node = list->head->next; struct mydata * data = (struct mydata *)node; //取数据的时候只要转换一下就可以了 printf("x = %d, y=%llu, z=%f\n", data->x, data->y, data->z); 方法非常多。

user: user-2
content: 你是说数据存储在一个数组里然后另外弄个链表管理它们吗？  　链表里放指针就好了啊，　或者如果性能很重要的话就用另外一个同样大小的数组，对应位置记录链表的ｎｅｘｔ序号，　类似这样的简化吧

user: user-3

user: user-0
content: 引用 5 楼 zhao4zhong1 的回复:照Linux内核的list抄一遍也不让？！  包含了其他的头文件啊

user: user-4
content: 照Linux内核的list抄一遍也不让？！

user: user-4
content: Linux源代码中有实现。

user: user-5
content: 给你一个我用的。 我也是从其他代码修改过来的。  			typedef struct List 			{ 				struct List *_Next; 				struct List *_Prev; 			} List;  			/* Define a list like so: 			* 			*   struct gadget 			*   { 			*       List  entry;   <-- doesn't have to be the first item in the struct 			*       int          a, b; 			*   }; 			* 			*   static List global_gadgets = LIST_INIT( global_gadgets ); 			* 			* or 			* 			*   struct some_global_thing 			*   { 			*       List gadgets; 			*   }; 			* 			*   Init( &some_global_thing->gadgets ); 			* 			* Manipulate it like this: 			* 			*   AddHead( &global_gadgets, &new_gadget->entry ); 			*   Remove( &new_gadget->entry ); 			*   AddAfter( &some_random_gadget->entry, &new_gadget->entry ); 			* 			* And to iterate over it: 			* 			*   struct gadget *gadget; 			*   LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry ) 			*   { 			*       ... 			*   } 			* 			*/  			/* add an element after the specified one */ 			__inline static void AddAfter(List *elem, List *to_add) 			{ 				to_add->_Next = elem->_Next; 				to_add->_Prev = elem; 				elem->_Next->_Prev = to_add; 				elem->_Next = to_add; 			}  			/* add an element before the specified one */ 			__inline static void AddBefore(List *elem, List *to_add) 			{ 				to_add->_Next = elem; 				to_add->_Prev = elem->_Prev; 				elem->_Prev->_Next = to_add; 				elem->_Prev = to_add; 			}  			/* add element at the head of the list */ 			__inline static void AddHead(List *list, List *elem) 			{ 				AddAfter(list, elem); 			}  			/* add element at the tail of the list */ 			__inline static void AddTail(List *list, List *elem) 			{ 				AddBefore(list, elem); 			}  			/* remove an element from its list */ 			__inline static void Remove(List *elem) 			{ 				elem->_Next->_Prev = elem->_Prev; 				elem->_Prev->_Next = elem->_Next; 			}  			/* get the _Next element */ 			__inline static List *Next(List const *list, List const *elem) 			{ 				List *ret = elem->_Next; 				if (elem->_Next == list) ret = NULL; 				return ret; 			}  			/* get the previous element */ 			__inline static List *Prev(List const *list, List const *elem) 			{ 				List *ret = elem->_Prev; 				if (elem->_Prev == list) ret = NULL; 				return ret; 			}  			/* get the first element */ 			__inline static List *Head(List const *list) 			{ 				return Next(list, list); 			}  			/* get the last element */ 			__inline static List *Tail(List const *list) 			{ 				return Prev(list, list); 			}  			/* check if a list is empty */ 			__inline static int Empty(List const *list) 			{ 				return list->_Next == list; 			}  			/* initialize a list */ 			__inline static void Init(List *list) 			{ 				list->_Next = list->_Prev = list; 			}  			/* count the elements of a list */ 			__inline static unsigned int Count(List const *list) 			{ 				unsigned count = 0; 				List const *ptr; 				for (ptr = list->_Next; ptr != list; ptr = ptr->_Next) 				{ 					count++; 				} 				return count; 			}  			/* move all elements from src to the tail of dst */ 			__inline static void MoveToTail(List *dst, List *src) 			{ 				if (Empty(src)) return;  				dst->_Prev->_Next = src->_Next; 				src->_Next->_Prev = dst->_Prev; 				dst->_Prev = src->_Prev; 				src->_Prev->_Next = dst; 				Init(src); 			}  			/* move all elements from src to the head of dst */ 			__inline static void MoveToHead(List *dst, List *src) 			{ 				if (Empty(src)) return;  				dst->_Next->_Prev = src->_Prev; 				src->_Prev->_Next = dst->_Next; 				dst->_Next = src->_Next; 				src->_Next->_Prev = dst; 				Init(src); 			}  			/* iterate through the list */ #define LIST_FOR_EACH(elem, list) for ((elem) = (list)->_Next; (elem) != (list); (elem) = (elem)->_Next)  			/* iterate through the list, with safety against removal */ #define LIST_FOR_EACH_SAFE(elem, safetynext, list) for ((elem) = (list)->_Next, (safetynext) = (elem)->_Next; (elem) != (list); (elem) = (safetynext), (safetynext) = (elem)->_Next)  			/* iterate through the list using a list entry */ #define LIST_FOR_EACH_ENTRY(elem, list, type, field) for ((elem) = LIST_ENTRY((list)->_Next, type, field); &(elem)->field != (list); (elem) = LIST_ENTRY((elem)->field._Next, type, field))  			/* iterate through the list using a list entry, with safety against removal */ #define LIST_FOR_EACH_ENTRY_SAFE(elem, safetynext, list, type, field) for ((elem) = LIST_ENTRY((list)->_Next, type, field), (safetynext) = LIST_ENTRY((elem)->field._Next, type, field); &(elem)->field != (list); (elem) = (safetynext), (safetynext) = LIST_ENTRY((elem)->field._Next, type, field))  			/* iterate through the list in reverse order */ #define LIST_FOR_EACH_REV(cursor,list) for ((cursor) = (list)->_Prev; (cursor) != (list); (cursor) = (cursor)->_Prev)  			/* iterate through the list in reverse order, with safety against removal */ #define LIST_FOR_EACH_SAFE_REV(elem, safetynext, list) for ((elem) = (list)->_Prev, (safetynext) = (elem)->_Prev; (elem) != (list); (elem) = (safetynext), (safetynext) = (elem)->_Prev)  			/* iterate through the list in reverse order using a list entry */ #define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) for ((elem) = LIST_ENTRY((list)->_Prev, type, field); &(elem)->field != (list); (elem) = LIST_ENTRY((elem)->field._Prev, type, field))  			/* iterate through the list in reverse order using a list entry, with safety against removal */ #define LIST_FOR_EACH_ENTRY_SAFE_REV(elem, safetynext, list, type, field) for ((elem) = LIST_ENTRY((list)->_Prev, type, field), (safetynext) = LIST_ENTRY((elem)->field._Prev, type, field); &(elem)->field != (list); (elem) = (safetynext), (safetynext) = LIST_ENTRY((elem)->field._Prev, type, field))  			/* macros for statically initialized lists */ #define LIST_INIT(list) { &(list), &(list) }  			/* get pointer to object containing list element */ #define LIST_ENTRY(elem, type, field) ((type *)((char *)(elem) - offsetof(type, field)))

user: user-6
content: （1）存指针，void* （2）使用宏，我曾经看到过一个文件khash.h，用C宏实现了一个模板哈希表，但是代码的可读性完全没有，而且难用

user: user-7
content: 想要 链表 跟 数据 解耦  ，  又不想用模板 ，  那么这是一个 插入式的双链表