Linux内核链表C实现细节

Linux通用链表C实现细节

ps:在宏定义中要使用连接符\来连接两行

1. 计算结构成员member所在结构中的距离第一个成员地址编号的差值

#define offset(type, member)\
((int)&(((type*)0)->member))

2. 计算返回实际的结构成员指针所在结构变量的首地址

#define node_ads(node,type,member)\
((type*)((void*)node-offset(type,member)))

3. 遍历链表

#define list_for_each(n,head)\
for(n = head->next; head != n; n = n->next)

4. 第二种遍历

#define list_for_each_2(obj, head, member)\
for(obj = node_ads(head->next, typeof(*obj), member);\
 head != &obj->member; obj = node_ads(obj->member.next,typeof(*obj), member))
具体实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//	遍历链表
#define list_for_each(n,head)\
	for(n=head->next;head!=n;n=n->next)

//	计算结构成员member所在结构中的距离第一个成员地址编号的差值
#define offset(type,member) ((int)&(((type*)0)->member))

//	计算返回实际的结构成员指针所在结构变量的首地址
#define node_to_obj(node,type,member)\
	((type*)((void*)node-offset(type,member)))

//	第二种遍历
#define list_for_each_entry(obj, head, member) \
	for(obj=node_to_obj(head->next,typeof(*obj),member);\
	head!=&obj->member;\
	obj=node_to_obj(obj->member.next,typeof(*obj),member))


typedef struct Node

{
	struct Node* prev;
	struct Node* next;
}Node;

//	创建链表
Node* create_list(void)
{
	Node* head = malloc(sizeof(Node));
	head->next = head;
	head->prev = head;
	return head;
}

void _add_list(Node* p,Node* n,Node* node)
{
	p->next = node;
	n->prev = node;
	node->next = n;
	node->prev = p;
}

//	头添加
void add_head_list(Node* head,Node* node)
{
	_add_list(head,head->next,node);	
}
//	尾添加
void add_tail_list(Node* head,Node* node)
{
	_add_list(head->prev,head,node);	
}

//	删除结点
void _del_list(Node* node)
{
	node->next->prev = node->prev;
	node->prev->next = node->next;
	node->next = node;
	node->prev = node;
}

//	判断链表是否为空
bool empty_list(Node* head)
{
	return head->next == head;	
}

//	头删除
Node* del_head_list(Node* head)
{
	if(empty_list(head)) return NULL;
	Node* temp = head->next;
	_del_list(temp);
	return temp;
}

//	尾删除
Node* del_tail_list(Node* head)
{
	if(empty_list(head)) return NULL;
	Node* temp = head->prev;
	_del_list(temp);
	return temp;
}

/* 	下面是用户编写的代码 */
typedef struct Student
{
	char name[20];
	char sex;
	char age;
	float score;
	Node node;
	int id;
}Student;

int main(int argc,const char* argv[])
{
	Node* head = create_list();
	/*
	Student* stu = malloc(sizeof(Student));
	printf("%u %u\n",(unsigned int)stu,(unsigned int)&stu->node);
	printf("%d %d\n",
		(int)(Student*)0,(int)(&((Student*)0)->node));
	printf("%d\n",offset(Student,node));
	*/
	for(int i=0; i<10; i++)
	{
		Student* stu = malloc(sizeof(Student));
		sprintf(stu->name,"hehe%d",i);
		stu->sex = i%2?'w':'m';
		stu->age = i+18;
		stu->score = rand()%100;
		stu->id = 1000+i;
		add_tail_list(head,&(stu->node));
	}
    Student* s = NULL;
list_for_each_entry(s,head,node)
{
	printf("%s %c %hhd %g %d\n",
	s->name,s->sex,s->age,s->score,s->id);
}
    
    //第一种遍历方式
Student* n1 = (Student*)del_tail_list(head);

Node* n = NULL;
list_for_each(n,head)
{
	//Student* stu = (Student*)n;
	Student* s = node_to_obj(n,Student,node);
	printf("%s %c %hhd %g %d\n",
	s->name,s->sex,s->age,s->score,s->id);
}
printf("------------\n");
printf("%s %c %hhd %g %d\n",
n1->name,n1->sex,n1->age,n1->score,n1->id);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值