C语言接口与实现学习笔记——链表

实现一个链表的一系列接口,体会了指针的用法

list.h

#ifndef LIST_INCLUDE
#define LIST_INCLUDE

#define T List_T
typedef struct T *T;
struct T
{
    T rest;
    void *first;
};

extern T List_append(T list, T tail);
extern T List_copy(T list);
extern T List_list(void *x, ...);
extern T List_pop(T list, void **x);
extern T List_push(T list, void *x);
extern T List_reverse(T list);
extern int List_length(T list);
extern void List_free(T *list);
extern void List_map(T list, void apply(void **x, void *cl), void *cl);
extern void **List_toArray(T list, void *end);

#undef T
#endif // LIST_INCLUDE

list.c

#include <stdarg.h>
#include <stddef.h>
#include "assert.h"
#include "mem.h"
#include "list.h"

#define T List_T

T List_push(T list, void *x)
{
    T p;

    NEW(p);
    p->first = x;
    p->rest = list;
    return p;
}

T List_list(void *x, ...)
{
    va_list ap;
    T list, *p = &list;

    va_start(ap, x);
    for(; x; x = va_arg(ap, void*))
    {
        NEW(*p);
        (*p)->first = x;
        p = &(*p)->rest;
    }
    *p = NULL;
    va_end(ap);
    return list;
}

T List_append(T list, T tail)
{
    T *p = &list;

    while(*p)
    {
        p = &(*p)->rest;
    }
    *p = tail;
    return list;
}

T List_copy(T list)
{
    T head, *p = &head;

    for(; list; list = list->rest)
    {
        NEW(*p);
        (*p)->first = list->first;
        p = &(*p)->rest;
    }
    *p = NULL;
    return head;
}

T List_pop(T list, void **x)
{
    if(list)
    {
        T head = list->rest;
        if(x)
        {
            *x = list->first;
        }
        FREE(list);
        return head;
    }
    else
    {
        return list;
    }
}

T List_reverse(T list)
{
    T head = NULL, next;

    for(; list; list = next)
    {
        next = list->rest;
        list->rest = head;
        head = list;
    }

    return head;
}

int List_length(T list)
{
    int n;

    for(n = 0; list; list = list->rest)
    {
        n++;
    }

    return n;
}

void List_free(T *list)
{
    T next;

    assert(list);
    for(; *list; *list = next)
    {
        next = (*list)->rest;
        FREE(*list);
    }
}

void List_map(T list, void apply(void **x, void *cl), void *cl)
{
    assert(apply);
    for(; list; list = list->rest)
    {
        apply(&list->first, cl);
    }
}

void **List_toArray(T list, void *end)
{
    int i, n = List_length(list);
    void **array = ALLOC((n+1)*sizeof(*array));

    for(i = 0; i < n; ++i)
    {
        array[i] = list->first;
        list = list->rest;
    }

    array[i] = end;
    return array;
}
时间: 2024-10-12 12:11:45

C语言接口与实现学习笔记——链表的相关文章

Go语言并发与并行学习笔记(一)

转:http://blog.csdn.net/kjfcpua/article/details/18265441 如果不是我对真正并行的线程的追求,就不会认识到Go有多么的迷人. Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据. 以下是我入门的学习笔记. 首先,并行!=并发, 两者是不同的,可以参考:http://concur.rspace.googlecode.com/hg/talk/concur.html G

互联网世界中的C语言——我的golang学习笔记:1(基础语法快速过)

前言 学习任何知识都会有一个学习背景 最近,我们团队乃至我司整个云服务,上go的呼声越来越高!新服务已经开始用go开发,部分现有Java版的服务重构为go也只是时间问题而已,故相关技术积累势在必行!在云网络的分布式服务乃至在一切高并发,分布式后台服务中,golang都有着很大的优势. 据我对国内互联网行业的实际考察,了解,目前国内主流互联网公司都在积极投入go的怀抱…… 青云更是全栈使用了go…… 还有火的一塌糊涂的docker. 它为云而生. 它为并发而生. 还有go的安全.简洁.高效 有良好

Go语言并发与并行学习笔记(三)

目录(?) [-] Go语言并发的设计模式和应用场景 生成器 服务化 多路复合 select监听信道 结束标志 菊花链 随机数生成器 定时器 TODO Go语言并发的设计模式和应用场景 以下设计模式和应用场景来自Google IO上的关于Goroutine的PPT:https://talks.golang.org/2012/concurrency.slide 本文的示例代码在: https://github.com/hit9/Go-patterns-with-channel 生成器 在Pytho

《r语言实战》菜鸟学习笔记(一)

打算学习一下r语言,不知道从什么地方开始学习,加上本人的数理统计基础比较薄弱,所以就漫无目的的从网上找教程. 其实我逛的最多的网站还是知乎,读了好多很好的答案后,我选择了两本书,<153分钟学会r><r语言实战>.前者大概扫了一眼,不太适合边看书边敲代码(我个人比较喜欢这种),所以后者就比较适合我,这套书还是比较适合菜鸟看的,我还看过<集体智慧编程>,很不错. 下面开始了第一段程序.(博客园没有r语言选项,只好用plain txt了) 1 age <- c(1,3

C语言一维数组初步学习笔记

数组 可以存储一组或者多组数值的变量,里面包含多个元素,数组的每个成员都是一个数组元素. 一维数组 定义:类型 数组名[常量表达式] = {值1, 值2, 值3…}; ? 1 2 3 4 int a[3] = {0, 1, 2}; float f[2] = {1.2, 2.3, 3.14}; char str[] = {'h', 'e', 'l', 'l', 'o'}; chat str1 = "iPhone";//这也是定义字符数组的方法,字符数组后面会详细讲解,这里先了解一下 当数

《r语言实战》菜鸟学习笔记(二)

这一部分将要说明R语言的数据类型以及数据输入方面的内容 因子 R语言中变量可以归结为名义型,有序型和连续变量. 名义型 :没有顺序之分的变量.如 天气 阴晴等 有序型:有顺序关系,但不是数量关系. 心情好 坏 适中等 连续型:就是同是有数量和顺序.当然这里的连续型并不是数学中的连续,也包括离散数据 名义型和有序型在R中称为因子. 下面介绍factor()函数 diabetes <- c("Type1", "Type2", "Type1",

Java学习笔记--链表

心在山东身在吴,飘蓬江海漫嗟吁. 他时若遂凌云志, 敢笑黄巢不丈夫. --水浒传 先上源代码,LinkedList类: 1 private static class Node<E> { 2 E item; 3 Node<E> next; 4 Node<E> prev; 5 6 Node(Node<E> prev, E element, Node<E> next) { 7 this.item = element; 8 this.next = nex

《r语言实战》菜鸟学习笔记(三)图形初阶

本节内容包括 图形的创建和保存 自定义符号.线条.颜色和坐标轴 标注文本和标题 控制图形维度 组合多个图形 1.使用图形 pdf("mygraph.pdf")#保存pdf 也可以png/jpeg/bmp/tiff/xfig...attach(mtcars) plot(wt, mpg) abline(lm(mpg-wt)) #求出回归参数,并作出线 title("Regression of MPG on Weight") detach(mtcars)dev.off()

C语言 排序算法 - 数据结构学习笔记

/**  功能:     排序   *日期:     2017年9月24日   *作者:     yzh   *开发环境:  QT   **/ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_STACK_LENGTH 100     //非递归快速排序调用栈 #define MAX_LENGTH 20            //数组最大值 //对于数值型 keyType #de