Linux C double linked for any data type

简介: /************************************************************************** * 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);
    }

 

目录
相关文章
|
1月前
|
Ubuntu Linux Windows
linux 挂载硬盘报错 "mount: unknown filesystem type 'ntfs'"
【10月更文挑战第7天】在Linux系统中挂载硬盘时遇到“mount: unknown filesystem type &#39;ntfs&#39;”错误,是因为Linux默认可能不支持NTFS文件系统。本文提供了解决方案:安装NTFS-3G软件包以支持NTFS,并检查内核是否已加载NTFS模块。对于Ubuntu/Debian系统,可使用`sudo apt-get install ntfs-3g`命令;对于CentOS/RHEL系统,则需先安装EPEL仓库再安装NTFS-3G。此外,还需确认硬盘设备名正确无误,并创建合适的挂载点目录。
412 2
|
11月前
|
Linux Shell
Linux命令(29)之type
Linux命令(29)之type
77 2
|
6月前
|
数据库
Greenplum【异常 03】COPY命令报错 > ERROR: invalid input syntax for type double precision: ““(问题分析及解决方案)数据去重
Greenplum【异常 03】COPY命令报错 > ERROR: invalid input syntax for type double precision: ““(问题分析及解决方案)数据去重
206 0
|
Linux Shell
Linux基本功系列之type命令实战
Linux基本功系列之type命令实战
131 0
Linux基本功系列之type命令实战
|
Linux 开发工具 开发者
有关Linux系统出现Malformed line 1 in source list /etc/apt/sources.list (type)问题的解决方式
以下内容仅代表个人意见,本人亲测有效,如果没有效果可以现将之前的sources.list备份的文件恢复 重要的事情说三遍:记得备份,记得备份,记得备份 本文中所阐述的问题大致是因为由于不正常的关闭影响的sources.list文件的异常,以导致这种问题生成的原因,因此在这里考虑进行重新创建sources.list文件来解决问题的处理方式 本蒟蒻在昨晚做Linux(我用的是Debian,教学要求 )的时候,因为要在 /etc/apt/sources.list里添加一些东西,但是更改完之后,发生了错误:
952 0
有关Linux系统出现Malformed line 1 in source list /etc/apt/sources.list (type)问题的解决方式
|
Linux 数据安全/隐私保护