//Linux内核链表(企业级链表)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#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;
}

C语言 Linux内核链表(企业级链表)的更多相关文章

  1. linux内核数据结构之链表

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

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

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

  3. 拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)

    在实际的工作中,我们可能会经常使用链表结构来存储数据,特别是嵌入式开发,经常会使用linux内核最经典的双向链表 list_head.本篇文章详细介绍了Linux内核的通用链表是如何实现的,对于经常使 ...

  4. linux内核中的链表

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

  5. linux内核的双链表list_head、散列表hlist_head

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

  6. Linux内核之旅 链表实现

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

  7. 例说Linux内核链表(一)

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

  8. Linux内核之数据双链表

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

  9. linux内核之链表操作解析

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

随机推荐

  1. Android-Selector用法

    在项目开发的时候,由于系统给出的控件不够美观,因此开发时领导常常要我更改下界面,用美工给的图片取代系统图片.开始时,我只是给按钮等设置一下背景图片,这样做虽然美观了,但界面看起来却比较死板,比如用户点 ...

  2. 二叉堆(binary heap)

    堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因 ...

  3. Cocos2d-X-3.0之后的版本的环境搭建

    由于cocos2d游戏开发引擎更新十分频繁,官方文档同步不够及时和完善.所以不要照着官方文档来照做生成工程. <点击图片就能进入网站> 具体的步骤: 1.获取cocos2d-X的源码v3. ...

  4. 问题解决——cout 输出 CString

    Unicode下 wcout<<strText.GetString()<<endl;

  5. 修改Tomcat服务器的端口号

    关键技术: Connector子元素下的port是设置服务器端口,而connection Timeout则是服务器连接超时单位为毫秒. 操作过程: (1)采用记事本打开Tomcat安装目录下的conf ...

  6. oracle表连接——处理连接过程中另外一张表没有相关数据不显示问题

    一个数据表基本上很难满足我们的查询要求,同时,将所有的数据都保存在一个表格中显然也不是一种好的数据库设计,为了避免数据的冗余,删除.更新异常,我们通常需要建立一张外键表,通过表连接,来获取我们自己想要 ...

  7. windows server 2003下安装.net framework 3.5 一直安装不成功

    安装包是在微软下载中心下的197m的文件 重启了也是不行,最后 找到.net framework 3.5 sp1 一个237m的安装包 安装成功了! Congratulations ! ​

  8. linux—【绝对路径与相对路径】与【【文件基本操作】】(4)

    [绝对路径与相对路径] 绝对路径:我们在获得一个文件的时候,从根目录到二级到更多级目录都写全了, 终才找到这个文件,这种方式就是“绝对路径” 相对路径:目标文件与我本身文件的相对位置 当前目录:./  ...

  9. zabbix_server 已死,但是 subsys 被锁

    一开始 grant all privileges on zabbix.*  to zabbix@localhost identified by 'password'; 将localhost改为ip后恢 ...

  10. 免费的无次数限制的各类API接口(2)

    之前整理过一些聚合数据上的免费API(各类免费的API接口分享,无限次),这次还有一些其他的进行了整理,主要是聚合数据上和API Store上的一些,还有一些其他的. 聚合数据提供30大类,160种以 ...