【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.

   此處的使用到了強制轉換,能不能想辦法去掉強制轉換,暫時還沒想到辦法,之後想到了再來解決。

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