内核链表 例题 C语言实现

embedded/2025/1/11 18:02:10/

问题:

将下面的数据节点信息转换为链表结构,并遍历输出。要求根据type的值来决定val的类型。

type为1代表bool类型,2代表整形,3代表浮点型。无需解析文本,直接赋值形成节点即可。


代码:

list.c
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include "list.h"/*定义Value共用体*/
typedef union{bool bool_val;int int_val;float float_val;
} Value;/*定义Data结构体*/
typedef struct Data{int key;int type;Value val;struct list_head list;
}Data;
/*初始化结点*/
Data create_node(int key,int type,char* val_str){Data node;node.key = key;node.type = type;/*根据类型存数据*/switch(type){case 1:node.val.bool_val = atoi(val_str) != 0;break;case 2:node.val.int_val = atoi(val_str);break;case 3:node.val.float_val = atof(val_str);break;default:printf("error\n");exit(1);}node.list.next = NULL;node.list.prev = NULL;return node;
}
/*输出结点*/
void print_node(Data *tmp){switch(tmp->type){case 1:printf("key = %d,val = %s\n",tmp->key,(tmp->val.bool_val == 0 ? "false":"true"));;break;case 2:printf("key = %d,val = %d\n",tmp->key,tmp->val.int_val);break;case 3:printf("key = %d,val = %.2f\n",tmp->key,tmp->val.float_val);break;default:printf("print error\n");exit(1);}
}int main(){struct list_head head;INIT_LIST_HEAD(&head);Data data1,data2,data3;/*初始化结点*/data1 = create_node(1,2,"10");data2 = create_node(2,1,"0");data3 = create_node(3,3,"22.5");/*把结点加入链表*/list_add(&data1.list, &head);list_add(&data2.list, &head);list_add(&data3.list, &head);struct list_head *pos;Data *tmp;printf("init list\n");/*遍历链表*/list_for_each(pos, &head){tmp = list_entry(pos, Data, list); // 获取当前结点print_node(tmp); // 输出结点}printf("\n");puts("del last\n");pos = get_last(&head);list_del(pos); // 删除末尾结点printf("after del:\n");/*遍历链表*/list_for_each(pos, &head){tmp = list_entry(pos, Data, list); // 获取当前结点print_node(tmp); // 输出结点}printf("\n");
}
list.h
/***********************************************************************************
Copy right:	Coffee Tech.
Author:			wanghan
Version:		V1.0
Date:			2025-1
Description:	从linux内核抽出来链表,可以做通用链表使用,可保留
***********************************************************************************/#ifndef _LIST_H
#define _LIST_H//定义核心链表结构
struct list_head
{struct list_head *next, *prev;
};//链表初始化
static inline void INIT_LIST_HEAD(struct list_head *list)
{list->next = list;list->prev = list;
}//插入结点
static inline void __list_add(struct list_head *new_list,struct list_head *prev, struct list_head *next)
{next->prev = new_list;new_list->next = next;new_list->prev = prev;prev->next = new_list;
}//在链表头部插入
static inline void list_add(struct list_head *new_list, struct list_head *head)
{__list_add(new_list, head, head->next);
}//尾部插入结点
static inline void list_add_tail(struct list_head *new_list, struct list_head *head)
{__list_add(new_list, head->prev, head);
}static inline void __list_del(struct list_head *prev, struct list_head *next)
{next->prev = prev;prev->next = next;
}//删除任意结点
static inline void list_del(struct list_head *entry)
{__list_del(entry->prev, entry->next);
}//是否为空
static inline int list_empty(const struct list_head *head)
{return head->next == head;
}//得到第一个结点
static inline struct list_head *get_first(const struct list_head *head)
{return head->next;
}//得到最后一个结点
static inline struct list_head *get_last(const struct list_head *head)
{return head->prev;
}static inline void __list_splice(const struct list_head *list,struct list_head *prev,struct list_head *next)
{struct list_head *first = list->next;struct list_head *last = list->prev;first->prev = prev;prev->next = first;last->next = next;next->prev = last;
}/*** list_splice - join two lists, this is designed for stacks* @list: the new list to add.* @head: the place to add it in the first list.*/
static inline void list_splice(const struct list_head *list,struct list_head *head)
{if (!list_empty(list))__list_splice(list, head, head->next);
}/*** list_splice_tail - join two lists, each list being a queue* @list: the new list to add.* @head: the place to add it in the first list.*/
static inline void list_splice_tail(struct list_head *list,struct list_head *head)
{if (!list_empty(list))__list_splice(list, head->prev, head);
}//后序(指针向后走)遍历链表
#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)#define list_for_each_safe(pos, n, head) \for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)//前序(指针向前走)遍历链表
#define list_for_each_prev(pos, head) \for (pos = (head)->prev; pos != (head); pos = pos->prev)#define offsetof_list(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)#define list_entry(ptr, type, member) ({			\const typeof( ((type *)0)->member ) *__mptr = (ptr);	\(type *)( (char *)__mptr - offsetof_list(type,member) ); })#endif

输出:


http://www.ppmy.cn/embedded/153079.html

相关文章

PySide6 Qt for Python Qt Quick参考网址

Qt QML BOOK&#xff1a; 《Qt for Python》 -Building an Application https://www.qt.io/product/qt6/qml-book/ch19-python-build-app#signals-and-slots Qt for Python&#xff1a;与C版本的差异即BUG处理&#xff08;常见的DLL文件确实的问题等&#xff09; Qt for Pyt…

asp.net core webapi 并发请求时 怎么保证实时获取的用户信息是此次请求的?

对于并发请求&#xff0c;每个请求会被分配到一个独立的线程或线程池工作线程上。通过 HttpContext 或 AsyncLocal&#xff0c;每个线程都能独立地获取到它自己的上下文数据。由于这些数据是与当前请求相关的&#xff0c;因此在并发请求时不会互相干扰。 在并发请求时&#xf…

【JAVA面试】接口和抽象类

在四层架构&#xff08;Controller, Service, ServiceImpl, Mapper&#xff09;的设计中&#xff0c;接口和抽象类的选择对代码的可扩展性和设计模式的使用有很大影响。以下是接口&#xff08;interface&#xff09;和抽象类&#xff08;abstract class&#xff09;的区别&…

统计学习方法(第二版) 第五章 决策树

本章主要讨论决策树模型&#xff0c;以及生成、剪枝和分类的方法。 剪枝方法的补充 统计学习方法(第二版) 第五章 补充-CSDN博客 目录 基础数学知识&#xff1a; 1.自信息量 2.互信息 3.平均自信息量和熵 4.熵函数的性质 5.联合熵和条件熵 6.平均互信息量&#xff08;…

蓝桥杯嵌入式速通(1)

1.工程准备 创建一文件夹存放自己的代码&#xff0c;并在mdk中include上文件夹地址 把所有自身代码的头文件都放在headfile头文件中&#xff0c;之后只需要在新的文件中引用headfile即可 headfile中先提前可加入 #include "stdio.h" #include "string.h"…

在离线环境中安装 `.rpm` 包的步骤

在一些环境中&#xff0c;可能无法直接通过网络安装软件包。特别是在没有互联网连接的情况下&#xff0c;我们仍然可以手动下载 .rpm 安装包并进行离线安装。本文将介绍如何在离线环境中安装多个 .rpm 包&#xff0c;确保软件的顺利安装和依赖关系的处理。 1. 将 .rpm 文件复制…

sql 函数

# 四则运算 - * / # 函数 distinct 、count、sum、max、min、avg、sum、round select concat(device_id 是,device_id ) device_id from device_id_apply_factor where device_id D6A42CE6A0; select concat_ws(|||,device_id ,factor_a ,module_type) from 、device_id_app…

SSL 证书格式和证书文件扩展名:完整指南

SSL 证书是什么以及它如何工作相当容易理解。但当涉及到在服务器上安装它时&#xff0c;有时&#xff0c;你可能觉得这是在处理火箭科学。 由于有如此多的SSL 证书格式与特定服务器要求相关&#xff0c;您更有可能感到困惑和沮丧&#xff0c;而不是从一开始就正确配置证书。但…