最近看binder,发现里面的数据结构链表,红黑树结构体只有自己的节点类型,没有存放我们的数据,不像java,可以给链表一个泛型,传入数据类型结构。很好奇它怎么能根据节点找到我们要的数据。有了下面的demo,解释一下。
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
};
struct data{
struct node dnode;
int type;
};
//java 链表结构里面 需要嵌套数据类型,而c语言链表结果不需要嵌套任何数据类型 感到很神奇
//他们只需要其他任何的数据结构保存他们的一个节点就好了.
//链表 指向的node,是其他任何数据结构的里面的一个节点。这样就达到了 链表串联起所有其他类型的作用。
//最后根据任何一个node 就可以找到他指向的数据结构
int main(){
//分配一个data结构的数据
struct data* data1 = malloc(sizeof(struct data));
data1->type = 1;
//创建链表的头节点,保存data数据结构里node的地址
struct node* head = &data1->dnode;
//创建第二个节点
struct data* data2 = malloc(sizeof(struct data));
data2->type = 2;
head->next = &data2->dnode;
//创建第三个节点
struct data* data3 = malloc(sizeof(struct data));
data3->type = 3;
head->next->next = &data3->dnode;
//下面的问题就是如何根据node 找到结构体的首地址的问题
struct node* curhead = head;
//我这里简单处理,把node放在结构体的首位,这样node的地址,就是结构体的首地址。
//linux里有一个函数:container_of 可以通过结构体里的节点 找到这个结构体的首地址
/*
* container_of(ptr, type, member)
* 作用:通过成员变量的地址得到它所在结构体的首地址
* 参数含义:
* ptr -- member类型定义的指针变量
* type -- 需要操作的数据类型,通常为结构体
* member -- type结构的成员名称
* * */
while(curhead){
printf("node val = %d\n",((struct data*)curhead)->type);
curhead = curhead->next;
}
return 0;
}