您的位置:首页 > 运维架构 > Linux

Linux C single linked for any data type

2015-07-05 15:21 369 查看
/**************************************************************************
*            Linux C single linked for any data type
* 声明:
*      提供一种单链接口,可以保存保存任何类型的数据,有时候这种需求在
*  很多场合还是会用到的。
*
*                                  2015-7-5 晴 深圳 南山平山村 曾剑锋
*************************************************************************/

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

一、cat single_linked.h
#ifndef __SINGLE_LINKED_H__
#define __SINGLE_LINKED_H__

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

typedef struct SINGLE_LINKED{
void* datap;
int size;
struct SINGLE_LINKED* next;
} single_linked;

typedef void (*single_linked_print)(void* data);
typedef int (*single_linked_delete)(void* data, void* linked_delete);
/**
* you should giving a vilid data dan size for save
*/
int check_data_size(void *data, int size);
/**
* create a single linked header
*/
single_linked* create_single_linked(void* data, int size);
/**
* add data to single linked at top
*/
int top_add_single_linked(void* data, int size, single_linked* header);
/**
* add data to single linked at tail
*/
int tail_add_single_linked(void* data, int size, single_linked* header);
/**
* delete data in single linked
*/
int delete_single_linked(void* data, single_linked* header, single_linked_delete func);
/**
* print all data in single linked
*/
void print_single_linked(single_linked* header, single_linked_print func);
/**
* empty the single linked
*/
void empty_single_linked(single_linked* header);
/**
* free all data in single linked
*/
void free_single_linked(single_linked* header);
#endif  //__SINGLE_LINKED_H__

二、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 single_linked.c
#include "single_linked.h"
/**
* create a single linked as header
*/
single_linked* create_single_linked(void *data, int size){
single_linked* header = malloc(sizeof(single_linked));
ERR(1, NULL == header, goto err; "create single linked header fail.\n");
header->next = NULL;
header->datap = NULL;
header->size = 0;

if(check_data_size(data,size)){
void* new_data = malloc(size);
ERR(1, NULL == new_data, goto new_data_err; "create single linked header with data fail.\n");
memcpy(new_data, data, size);
header->size = size;
header->datap = new_data;
}
return header;
new_data_err:
free(header);
err:
return NULL;
}

int check_data_size(void* data, int size){
return ((data != NULL) && (size > 0));
}

int top_add_single_linked(void* data, int size, single_linked* header){
ERR(1, NULL == header, return -1, "the header was NULL in top add single linked\n");
single_linked* new_node = NULL;

if(check_data_size(data, size)){
single_linked* new_node = malloc(sizeof(single_linked));
ERR(1, NULL == new_node, goto err; "top add malloc node fail.\n");
new_node->next = NULL;
new_node->datap = NULL;
new_node->size = 0;

void* new_data = malloc(size);
ERR(1, NULL == new_data, goto err1; "top add malloc data fail.\n");
memcpy(new_data, data, size);
new_node->size = size;
new_node->datap = new_data;

new_node->next = header->next;
/**
* I had pazzled at this point with (header->next = new_node->next)
*/
header->next = new_node;

}
return 0;
err1:
free(new_node);
err:
return -1;
}

/**
* add data to single linked at tail
*/
int tail_add_single_linked(void* data, int size, single_linked* header){
ERR(1, NULL == header, return -1, "the header was NULL in tail add single linked\n");
single_linked* new_node = NULL;

if(check_data_size(data, size)){
single_linked* new_node = malloc(sizeof(single_linked));
ERR(1, NULL == new_node, goto err; "top add malloc node fail.\n");
new_node->next = NULL;
new_node->datap = NULL;
new_node->size = 0;

void* new_data = malloc(size);
ERR(1, NULL == new_data, goto err1; "top add malloc data fail.\n");
memcpy(new_data, data, size);
new_node->size = size;
new_node->datap = new_data;

//new_node->next = header->next;
while(header->next)
header = header->next;
/**
* I had pazzled at this point with (header->next = new_node->next)
*/
header->next = new_node;
}
return 0;
err1:
free(new_node);
err:
return -1;
}

/**
* delete data in single linked
*/
int delete_single_linked(void* data, single_linked* header, single_linked_delete func){
ERR(1, ((NULL == data) || (NULL == header) || (NULL == func)), return; "you shouldn't giving NULL for delete single linkde\n");

single_linked* tmp = header->next;
single_linked* pre = header;
while(tmp){
/**
* you should giving a return value to decision delete this or not
*/
if(func(data, tmp->datap)){
pre->next = tmp->next;
tmp->next = NULL;
free(tmp->datap);
free(tmp);
tmp = pre->next;
}else{
pre = tmp;
tmp = tmp->next;
}
}
return 0;
}

/**
* print all data in single linked
*/
void print_single_linked(single_linked* header, single_linked_print func){
ERR(1, ((NULL == header) || (NULL == func)), return; "you shouldn't giving NULL for print single linkde\n");
single_linked* tmp = header->next;
while(tmp){
func(tmp);
tmp = tmp->next;
}
}

/**
* free all data in single linked
*/
void free_single_linked(single_linked* header){
ERR(1, NULL == header, return; "free a header with NULL\n");

single_linked* tmp = header->next;
single_linked* pre = header->next;
while(tmp){
pre = tmp;
tmp = tmp->next;
free(pre->datap);
free(pre);
}

if(header->datap != NULL){
free(header->datap);
header->datap = NULL;
}
header->next = NULL;
free(header);
header == NULL;
}

void empty_single_linked(single_linked* header){
ERR(1, NULL == header, return, "empty header was NULL\n");

single_linked* tmp = header->next;
single_linked* pre = header->next;
while(tmp){
pre = tmp;
tmp = tmp->next;
free(pre->datap);
free(pre);
}

if(header->datap != NULL){
free(header->datap);
header->datap = NULL;
}
header->next = NULL;
header->size = 0;
}

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

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

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

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

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

single_linked* header = create_single_linked(NULL, 0);

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

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

empty_single_linked(header);

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

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

printf("---------------free----------------->\n");
free_single_linked(header);
}

void print(void* data){
student* stu = (((single_linked*)data)->datap);
printf("student: id = %d, score = %d \n", stu->id, stu->score);
}

int delete(void* data, void* linked_data){
return (((student*)data)->id == ((student*)linked_data)->id) && (((student*)data)->score == ((student*)linked_data)->score);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: