通用链表实现方式(一)
c
struct node_t {
struct node_t *next;
};
struct person {
struct node_t node;
char *name;
int age;
};
struct dog {
struct node_t node;
char *name;
int age;
char *class;
};
在此链表中,node结构体被放在了最前面,因此当我们用node结构体存储不同类型(dog或者person)结构体信息时,node 结构体位置就是dog或者person结构体的位置。在想要使用dog或者person时,只需要使用强制类型转换的方法即可。
通用链表实现方式(二)
使用操作系统:Linux,RT-Thread
c
struct person {
char *name;
int age;
struct node_t node;
char *address;
};
struct dog {
char *name;
int age;
char *class;
struct node_t node;
};
在此链表中,node结构体的位置在最后面,因此我们需要根据person或者dog结构体的大小反推出他们的指针起始位置。
具体代码如下:
cpp
p = (struct person *)((char *)pre - (unsigned int)&((struct person *)0)->node);
n = (struct person *)((char *)next - (unsigned int)&((struct person *)0)->node);
pre指针转换为char*后加减操作是以字节为单位了,否则是以sizeof(struct node_t)为单位来进行加减计算。
unsigned int类型的强制转换是因为要减去对应的字节数。
通用链表实现方式(三)
使用操作系统:FreeRtos
cpp
struct node_t {
void *container;
struct node_t *next;
};
与前面俩种方法类似,如果直接在contianer存储person或者dog的结构体地址,那么就不需要再去计算或者反推对应结构体的地址了。