当前位置: 首页 > news >正文

c语言tips-结构体数组 VS 链表宏:`list_for_each_entry` 的优势与局限对比分析

0 . 写在开头

在嵌入式开发、操作系统内核或者一般的 C 语言项目中,我们经常需要管理一组结构体数据。对于初学者而言,使用结构体数组无疑是最直观的选择,数组简单、访问高效,代码逻辑也易于理解。然而,当项目变得更复杂、数据对象需要动态增删、或者不确定元素数量时,结构体数组开始显得捉襟见肘。这时,许多开发者会转向链表,尤其是在 Linux 内核中被广泛使用的宏式链表管理方式,比如 list_for_each_entry。本文将从实际使用角度出发,对比结构体数组与基于 list_for_each_entry内核链表遍历方式,分析它们在灵活性、性能、可维护性等方面的优劣,帮助你在实际工程中做出更合适的选择。

1. 示例代码对比

以下代码分别使用结构体数组和使用链表遍历的方式来管理一组结构体数据,分别做这种数据结构的建立和遍历

#include <stdio.h>
#include <stdlib.h>/* ------- 链表结构与宏 ------- */
struct list_head {struct list_head *next, *prev;
};#define INIT_LIST_HEAD(ptr) \do { (ptr)->next = (ptr); (ptr)->prev = (ptr); } while (0)#define list_entry(ptr, type, member) \((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))#define list_for_each_entry(pos, head, member)              \for (pos = list_entry((head)->next, typeof(*pos), member);    \&pos->member != (head);                            \pos = list_entry(pos->member.next, typeof(*pos), member))#define list_add_tail(new, head) do {           \(new)->prev = (head)->prev;                 \(new)->next = (head);                       \(head)->prev->next = (new);                 \(head)->prev = (new);                       \
} while (0)/* ------- 学生结构体 ------- */
struct student {int id;struct list_head list; // 仅用于链表方式
};#define STUDENT_COUNT 5int main() {printf("== 使用结构体数组管理 ==\n");struct student students[STUDENT_COUNT];for (int i = 0; i < STUDENT_COUNT; ++i) {students[i].id = i + 1;printf("Student id: %d\n", students[i].id);}printf("\n== 使用链表管理 ==\n");struct list_head student_list;INIT_LIST_HEAD(&student_list);for (int i = 0; i < STUDENT_COUNT; ++i) {struct student *s = malloc(sizeof(struct student));s->id = i + 1;list_add_tail(&s->list, &student_list);}struct student *s;list_for_each_entry(s, &student_list, list) {printf("Student id: %d\n", s->id);}return 0;
}

输出结果如下:
== 使用结构体数组管理 ==
Student id: 1
Student id: 2
Student id: 3
Student id: 4
Student id: 5

== 使用链表管理 ==
Student id: 1
Student id: 2
Student id: 3
Student id: 4
Student id: 5

我们将代码放到pythontutor运行,可以很直观的看到这两张数据结构的区别,并总结一下这两种方式的优缺点

在这里插入图片描述

场景 / 特性结构体数组list_for_each_entry 链表
元素数量固定✅ 适合❌ 不适合
动态增删元素❌ 不适合✅ 非常适合
代码简洁性✅ 简单直观❌ 依赖宏和嵌套结构
操作效率(遍历)✅ 更快(顺序内存)❌ 指针跳跃开销大
内存管理复杂度✅ 静态分配或一块申请❌ 手动分配和释放
实时系统 / 嵌入式开发✅ 适合小系统✅ 广泛用于内核、嵌入式协议栈

相关文章:

  • 配置 macOS 上的 Ruby 开发环境
  • python爬虫——气象数据爬取
  • 机器学习与深度学习16-概率论和统计学01
  • WEB3全栈开发——面试专业技能点P5中间件
  • CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14
  • 中文分词双向匹配
  • .Net 优秀框架 ABP全面详解
  • 【JMeter】接口断言
  • “一张网,万般用”——聊聊网络虚拟化到底怎么实现的
  • 数据库管理与高可用-MySQL故障排查与生产环境优化
  • 当文化遇见科技:探秘国际数字影像创新生态高地
  • 华硕a豆14 Air香氛版,美学与科技的馨香融合
  • 北京智乐活科技有限公司 适趣ai 二面 全栈
  • FAISS:高性能向量库
  • 佰力博科技与您探讨热释电测量的几种方法
  • RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
  • 博睿数据×华为, 共筑智慧金融新未来
  • React Native 是什么?为什么学它?
  • 井云科技|智能体变现新路径:从开发到盈利的关键跨越
  • day51 python CBAM注意力
  • 哈尔滨网络科技公司做网站/大数据营销系统软件
  • 网站制作综述/seo搜索引擎优化工具
  • 邮箱wordpress/临沂seo建站
  • 抖音运营/seo快速优化方法
  • h5响应式网站设计方案/策划推广
  • 成都在哪建设网站/org域名注册