【1】C++实现内核链表功能
2016-03-28 10:47
537 查看
内核链表:
特点:节点的指针域指向下一个节点/上一个节点的指针域,由此可以统一指针的类型,具有一般通用性,使用指针域跟数据入口地址【设为0地址】的offset来寻找数据入口,从而输出节点数据;内核链表一般为双向循环链表。
![](http://img.blog.csdn.net/20160328104803859?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
C++实现内核链表功能的例子,由此此处是参考C语言编写而成的,其中形参所用的为指针形参而不是引用,后期有时间再来修改
遇到的问题:
1.
![](http://img.blog.csdn.net/20160328104945424?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
此处的使用到了强制转换,能不能想办法去掉强制转换,暂时还没想到办法,之后想到了再来解决。
特点:节点的指针域指向下一个节点/上一个节点的指针域,由此可以统一指针的类型,具有一般通用性,使用指针域跟数据入口地址【设为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.
此处的使用到了强制转换,能不能想办法去掉强制转换,暂时还没想到办法,之后想到了再来解决。
相关文章推荐
- 设计模式--责任链模式C++实现
- C语言之指针 到现在还是很模糊 ->
- C++ Primer 5th - 1.5 类
- C++实现开机启动
- c++Primer5,总览与IO库和泛型算法
- c++ 函数返回引用
- leetcode Add Digits 之C语言实现
- leetcode Add Digits 之C++实现
- 设计模式--命令模式C++实现
- leetcode之Nim Game C语言实现
- leetcode之Nim Game C++实现
- leetcode 之Maximum Depth of Binary Tree 用 C语言实现
- 认识Visual C++各个版本
- 结构体大小问题
- c++ 强制类型转换 static_cast dynamic_cast reinterpret_cast和const_
- [面试] C++ STL(一)—— 向一个vector中添加N个元素,平均的添加的性能是?
- C语言中将数字转换为字符串的方法
- 进程间的相互通讯 C++
- c++ 中__declspec 的用法
- oj 中G++和C++区别(转)