起因

工作很少接触纯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)实现简单链表的更多相关文章

  1. 纯C语言(C89)实现动态数组

    起因 工作很少接触纯C项目,业余写着玩玩,不断雕琢 目标 纯C实现动态数组,提供方便易用泛型接口,避免依赖 实现 完全封装,隐藏结构体细节,不支持栈创建 拷贝存储,轻微性能代价换来易用性 vector ...

  2. 纯C语言INI文件解析

    原地址:http://blog.csdn.net/foruok/article/details/17715969 在一个跨平台( Android .Windows.Linux )项目中配置文件用 IN ...

  3. 经典数独游戏+数独求解器—纯C语言实现

    "心常乐数独小游戏"(下面简称"本软件")是一款windows平台下的数独游戏软件. 本软件是开源.免费软件. 本软件使用纯C语言编写,MinGW编译,NSIS ...

  4. 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊

    花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...

  5. geek青年的状态机,查表,纯C语言实现

    geek青年的状态机,查表,纯C语言实现 1. 问题的提出.抽象 建一,不止是他,不少人跟我讨论过这种问题:怎样才干保证在需求变更.扩充的情况下.程序的主体部分不动呢? 这是一个很深刻和艰难的问题.在 ...

  6. FastDFS是纯C语言实现,只支持Linux,适合以中小文件为载体的在线服务,还可以冗余备份和负载均衡

    一.理论基础 FastDFS比较适合以中小文件为载体的在线服务,比如跟NGINX(APACHE)配合搭建图片服务器. 分布式文件系统FastDFS FastDFS是纯C语言实现,只支持Linux.Fr ...

  7. 异想家纯C语言矩阵运算库

    Sandeepin最近做的项目中需要在嵌入式芯片里跑一些算法,而这些单片机性能不上不下,它能跑些简单的程序,但又还没到上Linux系统的地步.所以只好用C语言写一些在高级语言里一个函数就解决的算法了, ...

  8. 关于linux内核用纯c语言编写的思考

    在阅读linux2.6 版本内核的虚拟文件系统和驱动子系统的时候,我发现内核纯用c语言编写其实也是有一点不方便,特别是内核中大量存在了对象的概念,比如说文件对象,描述起来使用对象描述,但是对象在c语言 ...

  9. <Win32_20>纯c语言版的打飞机游戏出炉了^_^

    经过昨天的苦战,终于完成了纯C版的打飞机游戏——使用微信打飞机游戏的素材,不过玩法有些不同,下面会有详述 一.概述游戏的玩法.实现效果 1. 游戏第一步,简单判断一下,给你一个准备的时间: 2.选择& ...

随机推荐

  1. Bind DNS服务——转发与区域记录更新

    Linux基础服务--Bind DNS服务 Part4 转发与区域记录更新 一个DNS服务器不可能保存所有的区域记录,所以我们一般都会将其他的区域纪录转发到其他的服务器上进行解析. Bind9提供了全 ...

  2. Docker系列——Grafana+Prometheus+Node-exporter钉钉推送(四)

    近期搭建的服务器监控平台,来进行一个总结.主要分为监控平台的搭建.告警中心的配置以及消息的推送.推送的话,支持多种终端.具体详细可查看之前的博文,在这里罗列下,方便查看. Docker系列--Graf ...

  3. 不使用synchronized和lock,如何实现一个线程安全的单例

    单例,大家肯定都不陌生,这是Java中很重要的一个设计模式.稍微了解一点单例的朋友也都知道实现单例是要考虑并发问题的,一般情况下,我们都会使用synchronized来保证线程安全. 那么,如果有这样 ...

  4. daily plan

    想了想自己留的坑有点多了,写个计划提醒自己 一些没做出来的题 csp-s模拟测试54 z csp-s模拟测试b层加餐 string 平衡树+并查集 因为某杰的**安排,没时间改了csp-s模拟测试47 ...

  5. csp-s模拟测试41「夜莺与玫瑰·玫瑰花精·影子」

    夜莺与玫瑰 题解 联赛$T1$莫比乌斯$\%\%\%$ $dead$  $line$是直线 首先横竖就是$n+m$这比较显然 枚举方向向量 首先我们枚举方向向量时只枚举右下方向,显然贡献$*2$就是所 ...

  6. MySQL:一条SQL是如何执行的

    目录 MySQL基本架构 Server层 连接器 查询缓存 分析器 优化器 执行器 存储引擎层 InnoDB MyISAM Memory SQL执行流程 MySQL基本架构 在讲SQL语句是如何执行之 ...

  7. YOLO V4的模型训练

    1.YOLO V4模型训练的基本思路 所有机器学习涉及模型训练,一般都有训练集.验证集.测试集,因此需要准备数据集.有了数据集,再调用训练的算法,获取训练的结果.v3.v4模型训练方法相同. 2.YO ...

  8. js笔记11

    1.针对表单的 from  input  select  textarea type="radio/checkbox/password/button/tetx/submit/reset/&q ...

  9. CSS 多行文本溢出省略显示

    文本溢出我们经常用到的应该就是text-overflow:ellipsis了,相信大家也很熟悉,但是对于多行文本的溢出处理确接触的不是很多,最近在公司群里面有同事问到,并且自己也遇到过这个问题,所以专 ...

  10. C# datagridview 这是滚动条位置

    1.datagridview 设置 表格内容铺满,内容自动换行 dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True; ...