双向链表是一种比较常用的数据结构。
一个典型的例子如下:
struct student{
char* name;
int age;
struct student *prev;
struct student *next;
}
而在linux中对于双向链表的处理,有更多值的思考的地方
仍然用上面的例子.
struct list_head {
struct list_head *next, *prev;
};
struct student {
char* name;
int age;
list_head list;
}
其中list指向其它struct student变量中的list地址,也就是让struct student中的list交织成一个双向链表。这样做使得对于结构体中数据的操作和双向链表的操作相分离,在一定程度上降低了藕合性.
由于采用了这种结构,对于链表中内容的获取会发生一些变化.假设其中一个结点为student,那么对于第一种结构,只要student->next操作就可以获得下一个结点了.
那对于第二种怎么办呢?student->list->next指向的还是一个list_head结构体地址。
呵呵,答案就在这里。
(struct student *)( (char *)student->list->next - offsetof(struct student ,list )
其中offsetof(student struct ,list )表示在struct student中list与结构体struct student的偏移地址。也就是说虽然student->list->next 指向的是一个struct student中的list地址,但只要减去,list与结构体struct student的偏移地址,就可以得到该struct student结构的地址了,是不是很神奇啊.