Linux C double linked for any data type

/**************************************************************************
 *            Linux C double linked for any data type
 * 声明:
 *      提供一种双链接口,可以保存保存任何类型的数据。
 *
 *                                  2015-12-25 晴 深圳 南山平山村 曾剑锋
 *************************************************************************/

                    \\\\\\\\-*- 目录 -*-////////
                    |  一、cat double_linked.h
                    |  二、cat myerror.h
                    |  三、cat doulbe_linked.c
                    |  四、cat main.c
                    ---------------------------

一、cat double_linked.h
    #ifndef __DOUBLE_LINK_H__
        #define __DOUBLE_LINK_H__

        #include <stdio.h>
        #include <stdlib.h>
        #include "myerror.h"
        #include <string.h>

        typedef struct DOUBLE_LINKED{
            void* datap;
            int size;
            struct DOUBLE_LINKED* pre;
            struct DOUBLE_LINKED* next;
        } double_linked;

        typedef void(*double_linked_print)(double_linked* data);
        typedef int(*double_linked_delete)(void* data, double_linked* linked_data);

        void init_double_linked_node(double_linked* node);
        int check_data_size(void* data, int size);
        void empty_double_linked(double_linked* header);
        void _delete_double_linked_node(double_linked* pre, double_linked* next);
        void delete_double_linked_node(double_linked* node);
        /**
         * create a double linked for user
         */
        double_linked* create_double_linked(void* data, int size);
        void _add_double_linked(double_linked* current, double_linked* pre, double_linked* next);
        /**
         * top add doulbe linked
         */
        int top_add_double_linked(void* data, int size, double_linked* header);
        /**
         * tail add double linked
         */
        int tail_add_double_linked(void* data, int size, double_linked* header);
        /**
         * print all data in double linked
         */
        void print_double_linked(double_linked* header, double_linked_print func);
        /**
         * empty all data in double linked
         */
        void empty_double_linked(double_linked* header);
        /**
         * delete a element in the double linked
         */
        void delete_double_linked(void* data, double_linked* header, double_linked_delete func);
        /**
         * free all data in the double linked
         */
        void free_double_linked(double_linked* header);
    #endif

二、cat myerror.h
    #ifndef  _MYERROR_H
    #define  _MYERROR_H

    //serial error     1
    // error           2
    // warning         3
    // information     4

    #define    DEBUG1(...)      fprintf(stderr,"SERI ERR: " __VA_ARGS__);
    #define    DEBUG2(...)      fprintf(stderr,"ERR: " __VA_ARGS__);
    #define    DEBUG3(...)      fprintf(stdout,"WARNING: " __VA_ARGS__);
    #define    DEBUG4(...)      fprintf(stdout,"INFORMATION: " __VA_ARGS__);
    #define    DEBUG()            fprintf(stdout,"\033[32mbug at func( %s ) : %d\033[0m\n", __func__, __LINE__);

    #define    ERR(lever ,con, ret , ...)        \
       do                                        \
        {                                        \
            if(con)                                \
            {                                    \
                DEBUG##lever(__VA_ARGS__)        \
                ret;                            \
            }                                    \
        }while(0)

    #endif  //_MYERROR_H

三、cat doulbe_linked.c
    #include "double_linked.h"
    void init_double_linked_node(double_linked* node){
        node->next = node;
        node->pre = node;
        node->datap = NULL;
        node->size = 0;
    }

    int check_data_size(void* data, int size){
        return ((data != NULL) && (size > 0));
    }
    /**
     * create a double linked for user
     */
    double_linked* create_double_linked(void* data, int size){
        double_linked* header = malloc(sizeof(double_linked));
        ERR(1, NULL == header, goto err, "create double linked fail\n");

        init_double_linked_node(header);

        if(check_data_size(data, size)){
            void* new_data = malloc(size);
            ERR(1, NULL == new_data, goto err, "create double linked data fail\n");
            memcpy(new_data, data, size);
            header->size = size;
            header->datap = new_data;
        }

        return header;
    err:
        return NULL;
    }
    void _add_double_linked(double_linked* current, double_linked* pre, double_linked* next){
        pre->next = current;
        current->next = next;
        next->pre = current;
        current->pre = pre;
    }
    /**
     * top add doulbe linked
     */
    int top_add_double_linked(void* data, int size, double_linked* header){
        if(check_data_size(data, size)){
            double_linked* node = malloc(sizeof(double_linked));
            ERR(1, NULL == header, goto err, "create note fail.\n");

            init_double_linked_node(node);

            void* new_data = malloc(size);
            ERR(1, NULL == new_data, goto err, "create note data fail.\n");
            memcpy(new_data, data, size);
            node->size = size;
            node->datap = new_data;
            _add_double_linked(node, header, header->next);
            return 0;
        }
    err:
        return -1;
    }
    /**
     * tail add double linked
     */
    int tail_add_double_linked(void* data, int size, double_linked* header){
        if(check_data_size(data, size)){
            double_linked* node = malloc(sizeof(double_linked));
            ERR(1, NULL == header, goto err, "create note fail.\n");

            init_double_linked_node(node);

            void* new_data = malloc(size);
            ERR(1, NULL == new_data, goto err, "create note data fail.\n");
            memcpy(new_data, data, size);
            node->size = size;
            node->datap = new_data;
            _add_double_linked(node, header->pre, header);
            return 0;
        }
    err:
        return -1;

    }
    /**
     * print all data in double linked
     */
    void print_double_linked(double_linked* header, double_linked_print func){
        double_linked* tmp = header->next;
        while(tmp != header){
            func(tmp);
            tmp = tmp->next;
        }
    }
    void _delete_double_linked_node(double_linked* pre, double_linked* next){
        pre->next = next;
        next->pre = pre;
    }
    void delete_double_linked_node(double_linked* node){
        _delete_double_linked_node(node->pre, node->next);
        if(node->datap){
            free(node->datap);
        }
        init_double_linked_node(node);
        free(node);
    }
    /**
     * empty all data in double linked
     */
    void empty_double_linked(double_linked* header){
        double_linked* tmp = header->next;
        double_linked* pre = header;
        while(tmp != header){
            pre = tmp;
            tmp = tmp->next;
            delete_double_linked_node(pre);
        }
        init_double_linked_node(header);
        if(header->datap)
            free(header->datap);
        header->datap = NULL;
        header->size = 0;
    }
    /**
     * delete a element in the double linked
     */
    void delete_double_linked(void* data, double_linked* header, double_linked_delete func){
        double_linked* tmp = header->next;
        double_linked* pre = header;
        while(tmp != header){
            pre = tmp;
            tmp = tmp->next;
            if(func(data, pre)){
                delete_double_linked_node(pre);
            }
        }
    }
    void free_double_linked(double_linked* header){
        double_linked* tmp = header->next;
        double_linked* pre = header;
        while(tmp != header){
            pre = tmp;
            tmp = tmp->next;
            delete_double_linked_node(pre);
        }

        init_double_linked_node(header);
        if(header->datap)
            free(header->datap);
        header->datap = NULL;
        header->size = 0;
        free(header);
    }

四、cat main.c
    #include "double_linked.h"

    #define NR(x) ((sizeof(x))/sizeof(x[0]))

    /**
     * test struct
     */
    typedef struct STUDENT{
        int id;
        int score;
    }student;

    /**
     * callback function
     */
    void print(double_linked* node);
    int delete(void* data, double_linked* node);

    int main(int argc, char** argv){
        /**
         * demo data
         */
        student students[4] = {
            {1,1},
            {2,2},
            {2,2},
            {3,3},
        };
        double_linked* header = create_double_linked(NULL, 0);

        printf("--------------source--------------->\n");
        int i = 0;
        for(i = 0; i < NR(students); i++){
            printf("student: id = %d, score = %d\n", students[i].id, students[i].score);
        }

        printf("------------top add--------------->\n");
        for(i = 0; i < NR(students); i++){
            top_add_double_linked(&students[i],sizeof(student), header);
        }
        print_double_linked(header, print);

        empty_double_linked(header);

        printf("-----------tail add-------------->\n");
        for(i = 0; i < NR(students); i++){
            tail_add_double_linked(&students[i],sizeof(student), header);
        }
        print_double_linked(header, print);

        printf("-----------delete-------------->\n");
        student stu = {2,2};
        delete_double_linked(&stu, header, delete);
        print_double_linked(header, print);

        printf("-------------free-------------->\n");
        free_double_linked(header);
    }
    /**
     * impelement of the client print
     */
    void print(double_linked* node){
        student* stu = (student*)(node->datap);
        printf("student: id = %d, score = %d\n", stu->id, stu->score);
    }
    /**
     * impelement of the client delete
     */
    int delete(void* data, double_linked* node){
        student* stu = (student*)(node->datap);
        return (((student*)data)->id == stu->id) && (((student*)data)->score == stu->score);
    }

 

时间: 2024-11-08 22:49:04

Linux C double linked for any data type的相关文章

linux-fstat 读取3g大文件,获取文件大小错误显示Value too large for define data type

问题描述 fstat 读取3g大文件,获取文件大小错误显示Value too large for define data type fstat 读取3g大文件,获取文件大小错误显示Value too large for define data type 解决方案 提示信息:需要定义更大的数据类型呀. 解决方案二: Value too large for defined data typegcc 编译错误 Value too large for defined data typereaddir 报

powerDesigner如何同时显示name,code和data type

问题描述 我在word上看到pd的截图是:显示了 name和code和data type可是在我本地安装的pd显示是:值显示name和data type.应该在pd中如何设置?谢谢 解决方案 http://blog.csdn.net/spt110/article/details/8640849参考一下

GO语言变量及数据类型(variable, data type) 学习总结教程

1. variable 1.1 变量使用关键字 var 定义.变量是强类型的. package main import "fmt" var i int var c, python, java bool func main() {     fmt.Println(i, c, python, java) } 1.2 定义变量时候可以不指定类型,而是通过赋值获得类型 package main import "fmt" var i, j int = 1, 2 var c,

Function is a data type in Lua

在Lua中, 我们用到的函数, 其实是一个数据类型, 例如 :  [root@db-172-16-3-150 ~]# lua Lua 5.2.3 Copyright (C) 1994-2013 Lua.org, PUC-Rio > print(type(print)) function > print(type(function() end)) function > print(type({})) table > print(type("hello")) str

Linux系统su,passwd,ls,timestamp,cd,type及hash命令

su的用法: switch user 用法 # su [-l] 用户名    []内可简写也就是不写. 更换密码 # passwd   打完回车  连写两次新密码就行,注意复杂程度****** command命令  options 选项(选项自己也有的可以带参数)  arguments 参数 ls list 列表 列出.列出制定路径下的文件 pwd printing working derectory 显示当前的工作目录大致上就是显示当前目录下的文件吧或者显示当前你在哪个路径下. ls -l:长

linux中 iptables遇到iptables: Protocol wrong type for socket

 下面琰各位介绍一篇关于Linode vps iptables遇到iptables: Protocol wrong type for socket.错误的解决方法,希望文章对各位有帮助     想在linode vps centos 6.4上iptables加入限制ip连接数不能超过100的规则: iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 100 -j REJECT 出现错误: iptable

Parameter \&amp;#39; \&amp;#39;: No size set for variable length data type: String

http://blog.163.com/pinbo_jiankun/blog/static/13354648820138245630971/

【Agile Pair Coding】Data Type Mapping

介绍     今天下午用了1个小时左右,和同事Agile Pair Coding敏捷开发了一把,感觉挺爽的.     Agile Pair Coding给我们带来的直接好处是:相互不浪费时间(就两个人),高效:idea很快达成共识(就两个人),不纠结于无谓的讨论:idea立马coding,不沉迷于头脑风暴:代码更严谨:重构概率大:加深基情:相互学习,相互欣赏,相互指正:避免无知,避免自我感觉良好......     代码主要实现:从所有类型文件中,得到所有NE类型下的所有Object类型下的所有

Video for Linux Two API Specification revision0.24【转】

转自:http://blog.csdn.net/jmq_0000/article/details/7536805#t136 Video for Linux Two API Specification Revision 0.24 Michael H Schimek             <mschimek@gmx.at>            Bill Dirks Hans Verkuil Martin Rubli Copyright 1999, 2000, 2001, 2002, 2003,