嵌入式开发19天(内核链表)

==================内核链表==================

内核网站:https://www.kernel.org/      //可以自己下载 想要的内核


内核链表路径:/home/gec/Download/linux-2.6.35.7-gec/include/linux/list.h


内核链表与 其他链表的区别?

其实样子差不多 ,而内核链表的存在就是为了,能够兼容多种结构体而做的链表。


我们先来看看两个链表的结构体 

这是 内核链表:

typedef struct node
{
int data;
struct list_head list;

}listnode,*kernel_list;

内核链表是 在结构体里面 设置一个结构体来存储链表 


//这是 双向链表 :

typedef struct node
{
int data;
struct node *prev;
struct node *next;
}listnode,*double_list; 

双向链表是 在结构体里面 直接放置 头尾节点;


内核链表的特点:


内核结构元素不与特定类型结构相关,任何结构体都可通过内核的添加成为链表中的节点。



INIT_LIST_HEAD(struct list_head *list)初始化函数


list_add(struct list_head *new, struct list_head *head)实现将节点插入到节点head的后面


list_add_tail(struct list_head *new, struct list_head *head)将节点new插入到节点head的前面


list_del(struct list_head *entry)节点删除


list_replace(struct list_head *old,struct list_head *new)使用新节点替代旧节点old


list_replace_init(struct list_head *old,struct list_head *new)使用新节点替代旧节点old,且将旧节点重新初始化
list_move(struct list_head *list, struct list_head *head)是将list移动到head的后面,小结构体指针


list_move_tail(struct list_head *list,struct list_head *head)是将list移动到head的前面,小结构体


list_empty(const struct list_head *head)//判断head节点是否为NULL


list_for_each(pos, head)迭代遍历链表,要调用list_entry()得到大结构的指针


list_for_each_entry(pos, head, member)迭代遍历链表,得到大结构的指针




内核链表:
节点设计:
typedef struct node     //大结构体
{
int data;
struct list_head list; //小结构体
}listnode,*kernel_list;   


//初始化空链表
kernel_list list_init(void)
{
kernel_list list = malloc(sizeof(listnode));
if(list != NULL)
{
INIT_LIST_HEAD(&list->list);
return list;
}


return NULL;
}
//创建节点
kernel_list new_node(int data)
{
kernel_list new = malloc(sizeof(listnode)); //大结构体
if(new != NULL)
{
new->data = data;
new->list.next = NULL;
new->list.prev = NULL;
}
return new;
}






//查找节点


kernel_list find_node(int data,kernel_list head)
{
if(list_empty(&head->list))
return NULL;


kernel_list pos;
list_for_each_entry(pos,&head->list, list)//pos指针的是每个大结构体指针,迭代遍历链表,得到大结构的指针
{
if(pos->data == data)
return pos;
}
return NULL;
}


//显示链表


void show(kernel_list kerlist)
{

kernel_list pos;
list_for_each_entry(pos,&kerlist->list,list)//pos指针的是每个大结构体指针,迭代遍历链表,得到大结构的指针
{
printf("%d\t",pos->data);
}
printf("\n");
}
 
                                
练习:内核链表的移动操作,当输入一个正值时为插入操作;当输入一个负数时,删除对应的正数;输入两个数时,进行移动操作


移动操作步骤:
1、找到两个移动的节点的地址(大结构);
2、调用内核移动函数;

#include <stdio.h>
#include <stdlib.h>


#include "list.h"

int g_i = 0;
int g_j = 0;

typedef struct node
{
	int data;
	struct list_head list;	
	
}listnode,*kernel_list;

//初始化空链表
kernel_list list_init(void)
{
	kernel_list list = malloc(sizeof(listnode));
	if(list != NULL)
	{
		INIT_LIST_HEAD(&list->list);
		return list;
	}

	return NULL;
}
//创建节点
kernel_list new_node(int data)
{
	kernel_list new = malloc(sizeof(listnode)); //大结构体
	if(new != NULL)
	{
		new->data = data;
		new->list.next = NULL;
		new->list.prev = NULL;
	}
	return new;
}

//遍历内核链表
void show(kernel_list kerlist)
{
	
	kernel_list pos;
	list_for_each_entry(pos,&kerlist->list,list)//pos指针的是每个大结构体指针,迭代遍历链表,得到大结构的指针
	{
		printf("%d\t",pos->data);
	}
	printf("\n");
}

//查找数据对应的 大节点
kernel_list find_node(int data,kernel_list head)
{
	if(list_empty(&head->list))
		return NULL;

	kernel_list pos;
	list_for_each_entry(pos,&head->list, list)//pos指针的是每个大结构体指针,迭代遍历链表,得到大结构的指针
	{
		if(pos->data == data)
			return pos;
	}
	return 	NULL;
}

//获取输入端的数据
int get_number(char *buff)
{
	int count = 0;
	
	char *p;
	
	p = strtok(buff," ");
	count++;
	g_i = atoi(p);

	p = strtok(NULL," ");
	
	if(p != NULL)
	{
		g_j = atoi(p);
		
		count++;
	}
	
	return count;
	
	
}



int main(void)
{
	kernel_list kerlist = list_init();
	kernel_list new,tmp;
	char arr[20];
	int ret;
	
	
	while(1)
	{
		
		
		fgets(arr,20,stdin);
		ret = get_number(arr);
		
		
		if(ret == 1)
		{
				//插入操作
			if(g_i>0)
			{	
			new = new_node(g_i);
			list_add(&new->list, &kerlist->list);
			show(kerlist);
			}
			
			//删除操作
			if(g_i<0)
			{
				tmp = find_node(-g_i,kerlist);//得到大结构体的指针;
				list_del(&tmp->list);//传入小结构指针;
				free(tmp);
				show(kerlist);
			}
		}
		
		if(ret ==2)
		{
			new = find_node(g_i,kerlist);
			tmp = find_node(g_j,kerlist);
			
			list_move(&new->list,&tmp->list);
			show(kerlist);
			
			
		}
	}
	
	
	return 0; 
}



































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

交叉编译之王 hahaha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值