起因

工作很少接触纯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. 新增秒杀功能、优惠券、支付宝、Docker,newbee-mall升级版开源啦!

    最近是非常非常非常忙,一方面是公司的事情比较多,另外⼀点是最近在准备诉讼材料.⾄于诉讼的是谁,⼤家可以去看我之前写的几篇文章,所以本来这周是不打算更新文章的.不过,昨天慕课网的法务联系我的律师了,终于 ...

  2. 你知道这高效的12个Java精品库嘛?

    01. JUnit 第一个要说的当然是JUnit了,JUnit毕竟是Java圈目前最知名及常用的测试框架.JUnit之所以能够成为Java圈中最热门的测试库,是因为对于很多项目而言,单元测试是非常重要 ...

  3. 实现一个带有动效的 React 弹窗组件

    我们在写一些 UI 组件时,若不考虑动效,就很容易实现,主要就是有无的切换(类似于 Vue 中的 v-if 属性)或者可见性的切换(类似于 Vue 中的 v-show 属性). 1. 没有动效的弹窗 ...

  4. NOIP模拟测试29「爬山·学数数·七十和十七」

    爬山题解不想写了 学数数 离散化然后找到以每一个值为最大值的连续子段有多少个,然后开个桶维护 那么怎么找以每一个值为最大值的连续子段个数 方法1(我的极笨的方法) 考试时我的丑陋思路, 定义极左值为左 ...

  5. Huawei USG6530防火墙

    CF卡:(Compact Flash)最初是一种用于便携式电子设备的数据存储设备.作为一种存储设备,它革命性的使用了闪存 与sd卡的区别:SD卡的优点是安全.体积小巧,价格较之CF卡相对比较低,适合用 ...

  6. Django(70)接口版本控制

    前言   在RESTful规范中,有关版本的问题,用restful规范做开放接口的时候,用户请求API,系统返回数据.但是难免在系统发展的过程中,不可避免的需要添加新的资源,或者修改现有资源.因此,改 ...

  7. (1)Canal入门

    1.前言 在我们系统开发过程中,根据业务场景很多数据库数据并不会直接给用户访问的,需要同步保存到ElasticSearch.Redis等存储应用当中(例如最常见的是搜索页面的ElasticSearch ...

  8. testt

    一级标题 二级标题 三级标题 四级标题 l 1

  9. 二叉搜索树(Binary Search Tree)(Java实现)

    @ 目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...

  10. SQL 小知识笔记

    1.自动生成序列号 select row_number() over(order by field1) as row_number,* from t_table