您的位置:首页 > 编程语言 > C语言/C++

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

2016-03-28 10:47 537 查看
内核链表:
特点:节点的指针域指向下一个节点/上一个节点的指针域,由此可以统一指针的类型,具有一般通用性,使用指针域跟数据入口地址【设为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.


此处的使用到了强制转换,能不能想办法去掉强制转换,暂时还没想到办法,之后想到了再来解决。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: