c语言新建一个单向链表菜鸟,【图片】菜鸟的进击——玩转C语言链表【c程序设计吧】_百度贴吧...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
链表是我们学习C语言避不开的问题,就让我们一起飞过去看看吧:
1 定义链表
链表是C语言编程中常用的数据结构,比如我们要建一个整数链表,一般可能这么定义:
struct int_node {
int val;
struct int_node *next;
};
2 定义功能函数
为了实现链表的插入、删除、遍历等功能,另外要再实现一系列函数,比如:
void insert_node(struct int_node **head, int val);
void delete_node(struct int_node *head, struct int_node *current);
void access_node(struct int_node *head){
struct int_node *node;
for (node = head; node != NULL; node = node->next)
{
// do something here
}
}
如果我们的代码里只有这么一个数据结构的话,这样做当然没有问题,但是当代码的规模足够大,需要管理很多种链表,难道需要为每一种链表都要实现一套插入、删除、遍历等功能函数吗?
熟悉C++的同学可能会说,我们可以用标准模板库啊,但是,我们这里谈的是C,在C语言里有没有比较好的方法呢?
Linux内核中一般使用双向链表,声明为struct list_head,这个结构体是在include/linux/types.h中定义的,链表的访问是以宏或者内联函数的形式在include/linux/list.h中定义。
struct list_head { struct list_head *next, *prev;};
Linux内核为链表提供了一致的访问接口。
void INIT_LIST_HEAD(struct list_head *list);
void list_add(struct list_head *new, struct list_head *head);
void list_add_tail(struct list_head *new, struct list_head *head);
void list_del(struct list_head *entry);
int list_empty(const struct list_head *head);
以上只是从Linux内核里摘选的几个常用接口,更多的定义请参考Linux内核源代码。
3 处理链表
我们先通过一个简单的实作来对Linux内核如何处理链表建立一个感性的认识。
#include
#include "list.h" struct int_node
{
int val;
struct list_head list;
};
int main()
{
struct list_head head, *plist;
struct int_node a, b;
a.val = 2;
b.val = 3;
INIT_LIST_HEAD(&head);
list_add(&a.list, &head);
list_add(&b.list, &head);
list_for_each(plist, &head) {
struct int_node *node = list_entry(plist, struct int_node, list);
printf("val = %d\n", node->val);
}
return 0;
}
看完这个实作,是不是觉得在C代码里管理一个链表也很简单呢?
代码中包含的头文件list.h是我从Linux内核里抽取出来并做了一点修改的链表处理代码,现附在这里给大家参考,使用的时候只要把这个头文件包含到自己的工程里即可。
4 代码
list_head通常是嵌在数据结构内使用,在上文的实作中我们还是以整数链表为例,int_node的定义如下:
struct int_node {
int val;
struct list_head list;
};
使用list_head组织的链表的结构如下图所示:
遍历链表是用宏list_for_each来完成。
#define list_for_each(pos, head)
for (pos = (head)->next; prefetch(pos->next), pos != (head);
pos = pos->next)
在这里,pos和head均是struct list_head。在遍历的过程中如果需要访问节点,可以用list_entry来取得这个节点的基址。
#define list_entry(ptr, type, member)
\ container_of(ptr, type, member)
我们来看看container_of是如何实现的。如下图所示,我们已经知道TYPE结构中MEMBER的地址,如果要得到这个结构体的地址,只需要知道MEMBER在结构体中的偏移量就可以了。如何得到这个偏移量地址呢?这里用到C语言的一个小技巧,我们不妨把结构体投影到地址为0的地方,那么成员的绝对地址就是偏移量。得到偏移量之后,再根据ptr指针指向的地址,就可以很容易的计算出结构体的地址。
list_entry就是通过上面的方法从ptr指针得到我们需要的type结构体。
现在我们就从菜鸟变成不那么菜的鸟了_,当然,如果还有疑问的小伙伴可以直接联系我,也可以加群710520381,柳猫,跟你们不见不散……
c语言新建一个单向链表菜鸟,【图片】菜鸟的进击——玩转C语言链表【c程序设计吧】_百度贴吧...相关推荐
- c语言链表萌新,菜鸟的进击——玩转C语言链表
链表是我们学习C语言避不开的问题,就让我们一起飞过去看看吧: 1 定义链表 链表是C语言编程中常用的数据结构,比如我们要建一个整数链表,一般可能这么定义: struct int_node { int ...
- 用c语言程序画圣诞树,【图片】用C语言画一棵“圣诞树”(前方高能,学渣小心避让!)【广西科技大学吧】_百度贴吧...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #define PI 3.14159265359 float sx, sy; float sdCir ...
- python单链表逆序_C语言实现一个单向链表,并写程序把单向链表进行逆序?
上图是题目需要实现的效果. 纯小白才开始学C语言,求指导,只输出了0到9,不知如何逆序输出. 中间重复的代码部分应该是要优化一下的,但暂时还不知到该怎么写. #import typedef struc ...
- LISP 圆孔标记_在AUTOCAD中如何用lisp语言新建一个标注样式
标注样式要先建立字体样式.62616964757a686964616fe78988e69d8331333337616533 如果箭头没有块的话,要建立块. ;;;主程序标注样式 (defun Text ...
- C语言写一个猜数字游戏?我只想玩王者荣耀
#include <stdio.h> #include <time.h> #include <stdlib.h> //先构造函数 //1.菜单 2.游戏实现函数 3 ...
- c语言编写一个字母金字塔,【强迫症满足向】字母金字塔: C语言实现
本质是for循环练习,金字塔在文后 一.初级阶段:输出菱形星星 这是一个for循环小练习 为满足强迫症需求, Leo先放个图爽一爽 算法本身不难, 注意循环结束条件, 初值的设置, 利用等差公式等等 ...
- c语言写一个进出货管理,[源码和文档分享]基于C语言实现的超市管理系统
1 需求分析 超市随着市场经济和现代信息技术的的发展,不可必要的要卷入信息现代化的大潮,如何使用现代化的工具,使企业和经营者个人在最小的投入下获取最大的回报,成为每一个人的梦想.因此,在超市管理中引进 ...
- can帧格式 dlc_【图片】CAN扩展帧结构【汽车can总线吧】_百度贴吧
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1. 帧起始(Start of Frame) 标志数据帧(包含远程帧),它由一个显性位(0)构成,只有在总县处于空闲状态时,才允许开始发送.所有节点必须同 ...
- 商品分类列表功能实现php,【图片】B2B2C系统如何实现商品分类功能【thinkphp吧】_百度贴吧...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 B2B2C系统如何实现商品分类功能 需要完成一个独立的B2B2C系统,系统分类和店铺商品分类是必不可少的.让我们看看商品分类是什么:商品分类是概括一定范围 ...
最新文章
- s-sed(stream editor) 文本填充和编辑 基本使用
- python3.7安装教程linux_linux系统安装Python 3.7.x
- windbg检测句柄泄露(定位到具体代码)
- VIO-slam 系统构建
- C语言可变参数只会用算啥本事?看我来抽丝剥茧干翻它!
- appium GUI介绍
- server2008安装iis php,window server 2008 iis7+php安装配置
- Delphi拖放编程
- 程序员如何用“撞针“拯救 35 亿地球人?
- 数据结构基础学习(一)数组
- Reverse Linked List II -- LeetCode
- shell脚本 把一个文件的内容全部转换为大写
- 炒菜多放油:确实好吃,可是又不健康
- 神经网络 神经元_神经去耦
- 让面试官赞扬的IO读取方法:大文件进行词频统计(单线程与多线程分别解决)利用Buffer流简单又快捷
- groupmod 修改用户组信息
- python汇率换算注释_【菜鸟学Python】案例一:汇率换算
- Selenium中的EC模块
- BP神经网络实现异或功能
- linux系统怎么改回win7系统,linux系统怎么安装win7系统?