【1】C++实现内核链表功能

内核链表:

特点:节点的指针域指向下一个节点/上一个节点的指针域,由此可以统一指针的类型,具有一般通用性,使用指针域跟数据入口地址【设为0地址】的offset来寻找数据入口,从而输出节点数据;内核链表一般为双向循环链表。


C++实现内核链表功能的例子,由此此处是参考C语言编写而成的,其中形参所用的为指针形参而不是引用,后期有时间再来修改

/*******************************************************************
Author:	OJ_GDUT
Function:	imitate the linked list of kernel
Date:	2016-03-27
********************************************************************/
#include <iostream>
#include <typeinfo>

using namespace std;

/*
 *	define the pointer field
 */
struct list_head{
	list_head *prev;
	list_head *next;
};

list_head head_list;			//define the linked list head,此处不能声明为指针,因为如果声明为指针则并没有为struct list_head分配栈空间

/*
 *	test parameters
 */
#if 1
class score{
friend int main(void);
private:
	int num;
	int english;
	int math;

public:
	list_head list;
}stu1, stu2, stu3;
#else
struct score{
	int num;
	int english;
	int math;
	list_head list;
}stu1, stu2, stu3;
#endif

list_head *pos;					//define the loop cursor,此处可以声明为指针,因为之后会对其进行替换 
score *tmp;						//define the a pointer that points to score,此处可以声明为指针,因为之后会对其进行替换 

/*****************************************************
Function name: INIT_LIST_HEAD
Function:	init the linked list head 
Parameters:	
struct list_head *list:the list_head that will be init
*******************************************************/
static inline void  INIT_LIST_HEAD(list_head *list)
{
	list->next = list;
	list->prev = list;			//如果不对head_list进行初始化,此处的list->next/prev会无定义,从而出现访问冲突
}

/*****************************************************
Function name: list_add_tail
Function:	add the list from the tail
Parameters:	
list_head *l_new: the new node
list_head *head:	the list head
*******************************************************/
void list_add_tail(list_head *l_new, list_head *head)
{
	list_head *prev = head->prev;
	list_head *next = head;
	prev->next = l_new;
	next->prev = l_new;
	l_new->prev = prev;
	l_new->next = next;
}

/*****************************************************
Function name: list_for_each
Function:	add the list from the tail
Parameters:	
list_head *pos:	the &struct list_head to use as a loop cursor
list_head *head:	the head for your list
*******************************************************/
#define list_for_each(pos, head) for(pos = head->next; pos != head; pos = pos->next)

/*****************************************************
Function name: list_del
Function:	deletes entry from list
Parameters:	
list_head *entry:the element to delete from the list
*******************************************************/
static inline void list_del(list_head *entry)
{
	list_head *prev = entry->prev;
	list_head *next = entry->next;

	next->prev = prev;
	prev->next = next;
	entry->prev = nullptr;
	entry->next = nullptr;
}

/*****************************************************
Function name: main
Function:	test the linked_list 
Parameters:	void
*******************************************************/
int main(void)
{
	/*1.初始化表头*/
	INIT_LIST_HEAD(&head_list);

	/*2.定义节点并插入节点*/
	stu1.num = 1;
	stu1.english = 91;
	stu1.math = 81;
	list_add_tail(&(stu1.list), &head_list);

	stu2.num = 2;
	stu2.english = 92;
	stu2.math = 82;
	list_add_tail(&(stu2.list), &head_list);

	stu3.num = 3;
	stu3.english = 93;
	stu3.math = 83;
	list_add_tail(&(stu3.list), &head_list);

	/*3.遍历节点并取出节点*/
	/*
	 * 基本思路:通过decltype获取数据类型,并定义一个位于0地址的该数据,
	 *			 通过计算指针域到0地址处的差值,可以得到数据入口与指针
	 *			 域的差值,从而可以通过指针域-差值的方式来读取节点中的
	 *		     数据,从而达到通用双向循环链表的作用,此处是精华。
	 */
	list_for_each(pos, (&head_list))
	{
		decltype(tmp) test = 0;
		unsigned i = (unsigned)(&(test->list)) - (unsigned)test;
		tmp = (decltype(tmp))((unsigned)pos - i);
		cout << "No." << tmp->num << " " << "english is " << tmp->english << "," << "math is " << tmp->math << endl;
	}

	/*4.删除节点*/
	list_del(&(stu1.list));
	list_del(&(stu2.list));
	list_del(&(stu3.list));

	/*5.再次取出节点,检验节点是否删除*/
	list_for_each(pos, (&head_list))
	{
		decltype(tmp) test;
		unsigned i = (unsigned)(&(test->list)) - (unsigned)test;
		tmp = (decltype(tmp))((unsigned)pos - i);
		cout << "No." << tmp->num << " english is " << tmp->english << ",math is " << tmp->math << endl;
	}
	system("pause");
	return  0;
}

//#define l_offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER)
//#define container_of(ptr, type, member) ({const typeid(((type *)0)->member)*_mptr = (ptr); (type*)((char*)_mptr-l_offsetof(type,member));})

/*****************************************************
Function name: list_entry
Function:	get the data of list
Parameters:	
list_head *prt: the &struct list_head pointer
type:	the type of the struct this embeded in
member:	the name of the list_struct within the struct 
*******************************************************/
//#define list_entry(ptr, type, member)  ({type *test; unsigned i = test - &(test->member); ptr - i;})

遇到的问题:

1.

   此处的使用到了强制转换,能不能想办法去掉强制转换,暂时还没想到办法,之后想到了再来解决。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章