纯C语言(C89)实现简单链表
起因
工作很少接触纯C项目,业余写着玩玩,不断雕琢
目标
纯C实现简单链表,提供方便易用泛型接口,避免依赖
实现
完全封装,隐藏结构体细节,不支持栈创建
拷贝存储,轻微性能代价换来易用性
list.h
#ifndef LIST_H
#define LIST_H
#include <stddef.h>
typedef struct ListItem_ ListItem;
typedef struct List_ List;
extern List* list_new();
extern void list_free(List* l);
extern size_t list_length(List* l);
extern ListItem* list_head(List* l);
extern ListItem* list_tail(List* l);
extern ListItem* list_next(ListItem* e);
extern size_t list_data(ListItem* e, void** data);
extern int list_insert_next(List* l, ListItem* e, void* data_in, size_t size);
extern int list_remove_next(List* l, ListItem* e);
#endif // LIST_H
list.c
#include "list.h"
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
typedef struct ListItem_ {
struct ListItem_* next;
byte* data;
size_t size;
} ListItem;
typedef struct List_ {
size_t count;
ListItem* head;
ListItem* tail;
} List;
List* list_new() {
List* l = calloc(1, sizeof(List));
return l;
}
void list_free(List* l) {
while (list_length(l) > 0) {
list_remove_next(l, 0);
}
}
size_t list_length(List* l) {
return l->count;
}
ListItem* list_head(List* l) {
return l->head;
}
ListItem* list_tail(List* l) {
return l->tail;
}
ListItem* list_next(ListItem* e) {
return e->next;
}
size_t list_data(ListItem* e, void** data) {
if (!e) return 0;
*data = e->data;
return e->size;
}
int list_insert_next(List* l, ListItem* e, void* data_in, size_t size) {
ListItem* e_new = calloc(1, sizeof(ListItem));
if (!e_new) return -1;
e_new->data = calloc(size, sizeof(byte));
if (e_new->data) {
memcpy(e_new->data, data_in, size);
e_new->size = size;
} else {
free(e_new);
return -1;
}
if (l->count == 0) {
if (e) return -1;
l->head = e_new;
l->tail = e_new;
} else if (e) {
e_new->next = e->next;
e->next = e_new;
if (!e_new->next)
l->tail = e_new;
} else {
e_new->next = l->head;
l->head = e_new;
}
l->count ++;
return 0;
}
int list_remove_next(List* l, ListItem* e) {
ListItem* e_next;
if (l->count == 0) return -1;
if (e) {
if (!e->next) return -1;
e_next = e->next;
e->next = e_next->next;
} else {
e_next = l->head;
l->head = e_next->next;
if (l->count == 1) l->tail = 0;
}
free(e_next->data);
free(e_next);
l->count --;
return 0;
}
测试
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main(int argc, char *argv[]) {
List* l = list_new();
ListItem* it;
size_t l_len = 0;
int i, x, y, *p, n;
for (i=0; i<10; i++) {
list_insert_next(l,0,&i,sizeof(i));
}
l_len = list_length(l);
printf("l_len:%d \n", l_len);
while (list_length(l) > 0) {
if (!list_remove_next(l,0)) {
n = list_data(list_head(l), &p);
if (n) printf("list_head:%d size:%d \t", *p, n);
n = list_data(list_tail(l), &p);
if (n) printf("list_tail:%d size:%d \n", *p, n);
}
}
list_free(l);
return 0;
}
l_len:10
list_head:8 size:4 list_tail:0 size:4
list_head:7 size:4 list_tail:0 size:4
list_head:6 size:4 list_tail:0 size:4
list_head:5 size:4 list_tail:0 size:4
list_head:4 size:4 list_tail:0 size:4
list_head:3 size:4 list_tail:0 size:4
list_head:2 size:4 list_tail:0 size:4
list_head:1 size:4 list_tail:0 size:4
list_head:0 size:4 list_tail:0 size:4
纯C语言(C89)实现简单链表的更多相关文章
- 纯C语言(C89)实现动态数组
起因 工作很少接触纯C项目,业余写着玩玩,不断雕琢 目标 纯C实现动态数组,提供方便易用泛型接口,避免依赖 实现 完全封装,隐藏结构体细节,不支持栈创建 拷贝存储,轻微性能代价换来易用性 vector ...
- 纯C语言INI文件解析
原地址:http://blog.csdn.net/foruok/article/details/17715969 在一个跨平台( Android .Windows.Linux )项目中配置文件用 IN ...
- 经典数独游戏+数独求解器—纯C语言实现
"心常乐数独小游戏"(下面简称"本软件")是一款windows平台下的数独游戏软件. 本软件是开源.免费软件. 本软件使用纯C语言编写,MinGW编译,NSIS ...
- 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊
花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...
- geek青年的状态机,查表,纯C语言实现
geek青年的状态机,查表,纯C语言实现 1. 问题的提出.抽象 建一,不止是他,不少人跟我讨论过这种问题:怎样才干保证在需求变更.扩充的情况下.程序的主体部分不动呢? 这是一个很深刻和艰难的问题.在 ...
- FastDFS是纯C语言实现,只支持Linux,适合以中小文件为载体的在线服务,还可以冗余备份和负载均衡
一.理论基础 FastDFS比较适合以中小文件为载体的在线服务,比如跟NGINX(APACHE)配合搭建图片服务器. 分布式文件系统FastDFS FastDFS是纯C语言实现,只支持Linux.Fr ...
- 异想家纯C语言矩阵运算库
Sandeepin最近做的项目中需要在嵌入式芯片里跑一些算法,而这些单片机性能不上不下,它能跑些简单的程序,但又还没到上Linux系统的地步.所以只好用C语言写一些在高级语言里一个函数就解决的算法了, ...
- 关于linux内核用纯c语言编写的思考
在阅读linux2.6 版本内核的虚拟文件系统和驱动子系统的时候,我发现内核纯用c语言编写其实也是有一点不方便,特别是内核中大量存在了对象的概念,比如说文件对象,描述起来使用对象描述,但是对象在c语言 ...
- <Win32_20>纯c语言版的打飞机游戏出炉了^_^
经过昨天的苦战,终于完成了纯C版的打飞机游戏——使用微信打飞机游戏的素材,不过玩法有些不同,下面会有详述 一.概述游戏的玩法.实现效果 1. 游戏第一步,简单判断一下,给你一个准备的时间: 2.选择& ...
随机推荐
- 【C++】随机数,rand()与srand()函数
rand()函数 rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdlib.h, 其值为2147483647. 测试代码: #include<cstdl ...
- C++中封装和继承的访问权限
众所周知,C++面向对象的三大特性为:封装,继承和多态.下面我们就先对封装做一些简单的了解.封装是通过C++中的类来完成的,类是一种将抽象转换为用户定义类型的工具.类的定义如下: class circ ...
- Redmine部署
Redmine部署文章: 第一篇:Redmine部署 第二篇:Redmine部署中遇到的问题 部门内部需要项目开发维护的网站,这种网站有付费的,也有开源项目.这类项目管理与协作的工具主要的MS Sha ...
- 二、RabbitMQ 进阶特性及使用场景 [.NET]
前言 经过上一篇的介绍,相信大家对RabbitMQ 的各种概念有了一定的了解,及如何使用RabbitMQ.Client 去发送和消费消息. 特性及使用场景 1. TTL 过期时间 TTL可以用来指定q ...
- 开发小技巧之:unicode的排序和正则匹配
目录 简介 ASCII字符的排序 本地字符的排序 为什么不使用unicode进行排序 emoji的正则匹配 总结 简介 我们知道计算机最先兴起是在国外,出于当时计算机性能的考虑和外国常用字符的考虑,最 ...
- 14、iptables_nat源地址转换(内网共享上网)
14.1.环境说明: 1.架构图:
- Pygame 入门基本指南
最近正在利用 Python 制作一个小游戏,但对于 Pygame 不熟悉,故在学习的过程记录相关知识点 Pygame 中文文档下载:Here Pygame第1-1课:入门 什么是Pygame? Pyg ...
- Spring缓存的注解关键词解释
Spring缓存的注解关键词解释 @Cacheable支持缓存 @Cacheable可以标记在一个方法上,也可以标记在一个类上. 1.当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表 ...
- nmon工具安装及nmon analyser的使用
步骤一:下载nmon及nmon analyser工具 nmon:http://nmon.sourceforge.net/pmwiki.php 根据自己系统的版本下载相应的版本即可 nmon analy ...
- WPF教程十:如何使用Style和Behavior在WPF中规范视觉样式
在使用WPF编写客户端代码时,我们会在VM下解耦业务逻辑,而剩下与功能无关的内容比如动画.视觉效果,布局切换等等在数量和复杂性上都超过了业务代码.而如何更好的简化这些编码,WPF设计人员使用了Styl ...