linux内核链表c实现,C语言 Linux内核链表(企业级链表)

//Linux内核链表(企业级链表)

#define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

#define offscfof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER)

#define container_of(ptr,type,member) (type *)((char *)ptr-offscfof(type,member))

typedef struct _node{

struct _node *pNext;

}Node;

typedef struct _student1{

int num;

char name[];

Node mynode;

}Student1;

//说明:结构体也可以写成以下模式

//typedef struct _student1{

// Node mynode;

// int num;

// char name[20];

//}Student1;

//这样一来,就不需要计算链表节点属性在结构体中的偏移量了,简单实用

//我之所以写的复杂是为了深刻理解其原理

//创建链表

int SList_Create(Node **pout/*out*/);

//获取链表长度

int Get_List_Len(Node *pin/*in*/);

//查找指定位置节点

int FindNode(Node *pin/*in*/, Node **pdel/*out*/, int pos/*in*/);

//插入指定位置节点

int InsertOption(Node *pin/*in*/, Node *pnode/*in*/, int pos/*in*/);

//删除指定节点

int RemoveNode(Node *pin/*in*/, Node **pdel/*out*/, int pos/*in*/);

void main(){

//创建链表指针

Node *phead;

int i = ,j=;

int ret = SList_Create(&phead);

//说明:为什么我要创建一个无用的头节点

//理由①:不创建一个头节点,那么初始化函数SList_Create()就没有必要存在

//理由②:插入第一个节点的时候无法插入,以为没有头结点,所以插不进去第一个节点(这是主要理由)

if (ret!=)

{

printf("创建链表头节点失败!\n");

}

//添加新节点

Student1 *pa = (Student1 *)malloc(sizeof(Student1));

pa->num = ;

strcpy(pa->name, "小米");

pa->mynode.pNext = NULL;

ret=InsertOption(phead, &pa->mynode, Get_List_Len(phead));

if (ret != )

{

printf("添加新节点a失败!\n");

goto END;

}

Student1 *pb = (Student1 *)malloc(sizeof(Student1));

pb->num = ;

strcpy(pb->name, "小明");

pb->mynode.pNext = NULL;

ret = InsertOption(phead, &pb->mynode, Get_List_Len(phead));

if (ret != )

{

printf("添加新节点b失败!\n");

goto END;

}

//打印出所有的节点

for (j = ; j < Get_List_Len(phead); j++)

{

Node *temp = NULL;

Student1 *temp2 = NULL;

FindNode(phead, &temp, j);

if (temp==NULL)

{

printf("查询节点失败\n");

}

else{

temp2 = container_of(temp, Student1, mynode);

printf("学生的编号:%d;学生的姓名%s\n", temp2->num, temp2->name);

}

}

END:

//删除所有链表节点

while (Get_List_Len(phead)){

Node *temp = NULL;

Student1 *temp2 = NULL;

RemoveNode(phead, &temp, );

temp2 = container_of(temp, Student1, mynode);

if (temp == NULL)

{

printf("节点删除失败!\n");

}

else{

if (temp2 != NULL)

{

free(temp2);

}

}

}

//释放头节点

if (phead==NULL)

{

free(phead);

}

system("pause");

}

//创建链表(顺序创建链表)

int SList_Create(Node **pout/*out*/){

int ERRO_MSG = ;

if (pout==NULL)

{

ERRO_MSG = ;

printf("pout==NULL erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

Node *pM = (Node *)malloc(sizeof(Node));

pM->pNext = NULL;

*pout = pM;

return ERRO_MSG;

}

//获取链表长度

int Get_List_Len(Node *pin/*in*/){

Node *pHead = NULL, *pCurrent = NULL;

int index = ;

pCurrent = pin->pNext;

while (pCurrent){

pCurrent = pCurrent->pNext;

index++;

}

return index;

}

//查找指定位置节点

int FindNode(Node *pin/*in*/, Node **pnode/*out*/, int pos/*in*/){

int ERRO_MSG = ;

if (pin == NULL || pnode == NULL)

{

ERRO_MSG = ;

printf("pin == NULL || pnode==NULL erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL, *pPrior = NULL;

pCurrent = pPrior = pin->pNext;

if (pCurrent==NULL)

{

ERRO_MSG = ;

printf("链表中暂时没有数据 erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

int index = ;

while (pCurrent){

if (index==pos)

{

*pnode = pCurrent;

break;

}

pPrior = pCurrent;

pCurrent = pCurrent->pNext;

index++;

}

if (*pnode==NULL)

{

ERRO_MSG = ;

printf("链表中没有找到该节点 erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

return ERRO_MSG;

}

//插入指定位置节点

int InsertOption(Node *pin/*in*/, Node *pnode/*in*/, int pos/*in*/){

int ERRO_MSG = ;

if (pin == NULL || pnode==NULL)

{

ERRO_MSG = ;

printf("pin == NULL || pnode==NULL erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL,*pPrior=NULL;

pHead = pPrior = pin;

pCurrent = pin->pNext;

pMalloc = pnode;

if (pCurrent==NULL)

{

if (pos==)

{

pHead->pNext = pMalloc;

return ERRO_MSG;

}

else{

ERRO_MSG = ;

printf("链表为空,无法在指定位置插入节点\n", ERRO_MSG);

return ERRO_MSG;

}

}

int index = ;

while (pCurrent){

if (pos == index)

{

pPrior->pNext = pMalloc;

pMalloc->pNext = pCurrent;

return ERRO_MSG;

}

pPrior = pCurrent;

pCurrent = pCurrent->pNext;

index++;

}

pPrior->pNext = pMalloc;

return ERRO_MSG;

}

//删除指定节点

int RemoveNode(Node *pin/*in*/, Node **pdel/*out*/, int pos/*in*/){

int ERRO_MSG = ;

if (pin == NULL || pdel==NULL)

{

ERRO_MSG = ;

printf("pin == NULL || pdel==NULL erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL, *pPrior = NULL;

pHead = pPrior = pin;

pCurrent = pin->pNext;

if (pCurrent==NULL)

{

ERRO_MSG = ;

printf("你要删除的链表为空! erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

int index = , flag = ;

while (pCurrent){

if (index == pos)

{

pPrior->pNext = pCurrent->pNext;

*pdel = pCurrent;

break;

}

pPrior = pCurrent;

pCurrent = pCurrent->pNext;

index++;

}

if (*pdel==NULL)

{

ERRO_MSG = ;

printf("链表中没有该位置的节点! erro msg:%d\n", ERRO_MSG);

return ERRO_MSG;

}

return ERRO_MSG;

}

72f57ddcdfb84b20605ca73c74f9cbe8.png

linux内核数据结构之链表

linux内核数据结构之链表 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结构不一样,只有前驱和后继指针,而没有数据域.后来看代码注释发现该 ...

linux内核数据结构之链表【转】

转自:http://www.cnblogs.com/Anker/p/3475643.html 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结 ...

linux内核中的链表

1.内核中的链表 linux内核链表与众不同,他不是把将数据结构塞入链表,而是将链表节点塞入数据,在2.1内核中引入了官方链表,从此内核中所有的链表使用都采用此链表,千万不要在重复造车轮子了!链表实现 ...

linux内核的双链表list&lowbar;head、散列表hlist&lowbar;head

一.双链表list_head 1.基本概念 linux内核提供的标准链表可用于将任何类型的数据结构彼此链接起来. 不是数据内嵌到链表中,而是把链表内嵌到数据对象中. 即:加入链表的数据结构必须包含一个 ...

Linux内核之旅 链表实现

#include "stdio.h" #include "stdlib.h" struct list_head{ struct list_head *prev; ...

例说Linux内核链表(一)

介绍 众所周知,Linux内核大部分是使用GNU C语言写的.C不同于其它的语言,它不具备一个好的数据结构对象或者标准对象库的支持. 所以能够借用Linux内核源代码树的循环双链表是一件非常值得让人高 ...

Linux内核之数据双链表

导读 Linux 内核中自己实现了双向链表,可以在 include/linux/list.h 找到定义.我们将会首先从双向链表数据结构开始介绍内核里的数据结构.为什么?因为它在内核里使用的很广泛,你只 ...

linux内核之链表操作解析

本文只是对linux内核中的链表进行分析.内核版本是linux-2.6.32.63.文件在:linux内核/linux-2.6.32.63/include/linux/list.h.本文对list.h ...

linux内核链表---挑战常规思维

一.普通链表 1.一般教材上的链表定义如下: struct node{ int content: node *next: }: 它将指针域放在链表节点中,上一个节点指针域中的值指向下一个节点的首地址, ...

随机推荐

继承自NSObject的不常用又很有用的函数(2)

函数调用 Objective-C是一门动态语言,一个函数是由一个selector(SEL),和一个implement(IML)组成的.Selector相当于门牌号,而Implement才是真正的住户( ...

iOS - Swift NSTimer&Tab;&Tab;定时器

前言 public class NSTimer : NSObject 作用 在指定的时间执行指定的任务. 每隔一段时间执行指定的任务. 1.定时器的创建 当定时器创建完(不用 scheduled 的, ...

Codeforces Round &num;368 &lpar;Div&period; 2&rpar; A&period; Brain&&num;39&semi;s Photos (水题)

Brain's Photos 题目链接: http://codeforces.com/contest/707/problem/A Description Small, but very brave, ...

Nginx源码研究七:nginx的location指令分析

在nginx的配置文件nginx.conf中,我们在配置server的时候,会配置一下location指令,这个location指令是提供给用户来配置对于符合指令的http请求,采用该指令内部的处理方 ...

&lpar;中等&rpar; POJ 2886 Who Gets the Most Candies&quest; &comma; 反素数&plus;线段树。

Description N children are sitting in a circle to play a game. The children are numbered from 1 to N ...

UGUI 字体背景长度自适应

本文实现以下需求: 在UGUI中 Text为动态添加 要使Text字体背景随着Text的长度而变化 之前还在赞叹UGUI的强大 转念一想,UGUI中好像没有可以实现此功能的组件 也想出了一种办法 把背 ...

BZOJ 2733 永无乡

splay启发式合并 启发式合并其实就是把集合数量小的合并到集合数量大的里去. 怎么合并呢,直接一个一个插入就行了.. 用并查集维护连通性,find(i)可以找到所在splay的编号 这题好像还可以合 ...

工具类:Colletions ,Arrays(静态导入,可变参数,强循环)

一.Collecti 专门用来操作集合的工具类,没有构造函数,全静态方法. 常用方法: static > voi ...

MS SqlServer还原数据库,出现媒体簇的结构不正确

出现此问题,是数据库版本过低导致,只要保证连接实例所在的版本号>=要还原的数据库的版本号,即可还原成功. 可以使用select @@VERSION,查看当前实例版本.

VirtualAlloc申请进程空间

https://baike.baidu.com/item/VirtualAlloc       百度百科 https://msdn.microsoft.com/zh-cn/library/window ...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值