#define LIST_ENTRY(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
使用这个宏的作用:
- ptr 为指向type类型结构体的一个成员的指针。
- 这个成员就是member。
- 通过这个宏我们就可以得到包含ptr指向的成员的结构体的首地址。
通常的应用场景:
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
#define LIST_ENTRY(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
//linux 的通用双向链表节点结构
//该结构只包含前后指针,没有具体节点数据,所以说是通用节点
//只做串联工作,节点数据就依靠 LIST_ENTRY 来取
struct list_head {
struct list_head *next, *prev;
};
struct mynode{
int data = 1; //data 为我们的节点数据
struct list_head link;
};
//最后的链子就是 mynode.link -> next_mynode.link... 只有link在链子中
//当我们拿到一个link 要取data 就可以用
int main()
{
mynode mylist[10];
mylist[0].link.prev = &mylist[9].link;
mylist[0].link.next = &mylist[1].link;
int pre;
for(int i = 1; i<9; i++)
{
mylist[i].data = i + 1;
mylist[i].link.prev = &mylist[i-1].link;
mylist[i].link.next = &mylist[i+1].link;
}
mylist[9].data = 10;
struct list_head* list_node = &mylist[0].link;
struct mynode* data_str;
data_str = LIST_ENTRY(list_node,mynode,link);
cout<<data_str->data<<endl;
while(list_node->prev != list_node->next)
{
data_str = LIST_ENTRY(list_node->next,mynode,link); //通过link成员转化成整个结构体指针
cout<<data_str->data<<endl;
list_node->next = list_node->next->next; //通过next来遍历节点
list_node->next->prev = list_node;
}
return 0;
};