起因

工作很少接触纯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. ThreadPoolExecutor参数详解

    ThreadPoolExecutor全部参数的构造函数 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long ke ...

  2. 在Intellij IDEA中查看TestNG自带的测试报告

    执行TestNG框架的测试用例,会生成测试报告.如果在IDEA中看不到,可做如下配置. 1. 点击IDEA工具栏中Run->Edit Configuration菜单,或者直接点击右上角编辑配置的 ...

  3. c#json将字符串反序列化成对象时不新建类的做法

    在服务端代码文件中加上struct结构体就能解决 struct LocationInfo { public string LocationID { get; set; } public string ...

  4. excel VBA正则匹配单元格符号,并按符号把单元格拆分行(这里是按第一列分行,分行是从活动单元格的行开始,分行前需要选择所有需要填充内容的列,否则需要后期手动填充)

    Sub W()   ' MsgBox "行数:" & Selection.Rows.Count    Dim rows_count As Integer    Dim ro ...

  5. UnityBug之KeyStore

    UnityException: Can not sign the applicationUnable to sign the application; please provide passwords ...

  6. 16、lamp的搭建

    搭建web02服务器作为web01的负载均衡服务器: httpd和nginx配置比较相似,也有虚拟主机,一个http服务需要配置多个站点,基于ip(基本用不到).端口(内部网站).域名(外部网站): ...

  7. 深入学习Netty(3)——传统AIO编程

    前言 之前已经整理过了BIO.NIO两种I/O的相关博文,每一种I/O都有其特点,但相对开发而言,肯定是要又高效又简单的I/O编程才是真正需要的,在之前的NIO博文(深入学习Netty(2)--传统N ...

  8. 整理!企业选择好用的CRM系统的要点(上)

    随着市场经济的发展,对任何行业的企业来说,客户都是非常重要的一个部分.CRM系统帮助企业做到以客户为中心,它可以根据客户的具体要求进行跟进和反馈,在很大程度上提高公司的客户服务水平和客户满意度,进而提 ...

  9. redis学习笔记(三)——redis的命令大全总结

    总结了一些redis五种存储类型的常用命令以及一些通用操作命令,不是很全,是在学习的时候将学到的做了个汇总,使用的时候可以查一下. 笔记写在表格里面了,不好粘贴.......后面的直接截图了..... ...

  10. mybatis 配置的log4j文件无效,不能正常显示日志信息

    正在学习mybatis,配置好后log4j.properties文件后,日志信息不能正常显示,没有效果. 查看了一下mybatis的相关文档,在日志一栏找到问题愿意 原因是我们的mybatis选了其他 ...