0%

04ds_05day

==============================
2022-8-5
==============================

note

一.早测
    完成有头双向循环链表的功能
    1.创建头结点
    2.插入数据结点
    3.遍历链表
    4.销毁链表
    5.查找结点
    6.删除结点
    7.拿出结点
只写声明和实现,不用写调用(llist.c 和 llist.h)

=================================
作业
1.把这一周讲过的内容都完完整整的复习一遍
2.把三个版本的通用性强的链表重新实现一遍
3.在纸上写链表的代码
=================================

通用性强的链表

结点图

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdio.h>
#include <string.h>
#include "llist.h"

#define NAMESIZE 20//字符数组的成员个数

struct stu//客户自己创建的数据结构体
{
int id;
char name[NAMESIZE];
int math;
int age;
int tel;
};

void print(const void *data)
{
const struct stu *p = data;
printf("%d %s %d %d %d\n",p->id,p->name,p->math,p->age, p->tel);
}

int id_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const int *k = key;

return !(p->id - *k);
}

int name_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const char *k = key;

return !(strcmp(p->name, k));
}

int tel_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const int *k = key;

return !(p->tel - *k);
}

int main(void)
{
LLIST *handler = NULL;//handler指针指向头结点
struct stu data;//存放客户自己的数据
struct stu save;//存储拿出的数据
struct stu *find = NULL;//指向找到的数据
int i = 0;//循环变量
int ret = 0;//接收返回值
int find_id = 100;
int find_tel = 10002;
char *find_name = "stu4";

handler = llist_create(sizeof(struct stu));
//创建头结点
if(handler == NULL)//判断头结点是否创建失败
return -1;//创建失败,结束程序,并且返回-1

for(i = 0; i < 5; i++)
{
data.id = 100 + i;//存储数据
sprintf(data.name, "stu%d", i);//存储数据
data.math = 100 - i;//存储数据
data.age = 20 + i;//存储数据
data.tel = 10000 + i;//存储数据
llist_insert(handler,&data,TAILINSERT);//插入数据
}

llist_display(handler, print);//遍历链表

printf("============================\n");
/*
find = llist_find(handler, &find_tel, tel_cmp);//查找
if(find == NULL)//判断是否没有找到
printf("Not Find It!\n");
else
{
printf("Find It!\n");
print(find);
}
*/
#if 0
ret = llist_delete(handler, &find_tel, tel_cmp);
if(ret != 0)
printf("Delete It Is Failed!\n");
else
printf("Delete It!\n");
#else
ret = llist_fetch(handler, &find_tel, tel_cmp, &save);
if(ret != 0)
printf("Fetch It Is Failed!\n");
else
{
printf("Fetch It!\n");
print(&save);
}
#endif

printf("============================\n");

llist_display(handler, print);//遍历链表

llist_destroy(handler);//销毁链表

return 0;
}

llist.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef __LLIST_H
#define __LLIST_H

#define HEADINSERT 0
#define TAILINSERT 1

typedef void (*llist_op)(const void *);//定义函数指针类型
typedef int (*llist_cmp)(const void *,const void *);

struct llist_node//数据结点的结构体
{
void *data;//data指针指向数据
struct llist_node *prev;//prev指针指向前驱
struct llist_node *next;//next指针指向后继
};

typedef struct llist_head//头结点的结构体
{
int size;//保存客户创建的结构体的大小
struct llist_node head;//
}LLIST;

LLIST *llist_create(int );//创建头结点

int llist_insert(LLIST *, const void *, int );//插入数据

void llist_display(LLIST *, llist_op);//遍历链表

void llist_destroy(LLIST *);//销毁链表

void *llist_find(LLIST *, const void *, llist_cmp);//查找

int llist_delete(LLIST *, const void *, llist_cmp);//删除

int llist_fetch(LLIST *, const void *, llist_cmp, void *);

#endif

llist.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "llist.h"

LLIST *llist_create(int size)
{
LLIST *handler = NULL;//指向头结点的指针

handler = malloc(sizeof(LLIST));//为头结点开辟空间
if(handler == NULL)//判断头结点空间是否开辟失败
return NULL;//开辟失败,结束函数,并且返回NULL
handler->size = size;//把客户结构体大小存储起来
handler->head.prev = &handler->head;//前驱指向自己
handler->head.next = &handler->head;//后继指向自己
return handler;//把指向头结点的指针返回
}

int llist_insert(LLIST *handler,const void *data,int mode)
{
struct llist_node *p = &handler->head;//保存头结点地址
struct llist_node *newnode = NULL;//保存新建的数据结点

newnode = malloc(sizeof(struct llist_node));//数据结点
if(newnode == NULL)//判断数据结点是否开辟失败
return -1;//开辟失败,结束函数,并且返回-1

newnode->data=malloc(handler->size);//开辟数据空间
if(newnode->data == NULL)//判断数据空间是否开辟失败
{
free(newnode);//释放数据结点的空间
return -2;//数据空间开辟失败,结束函数,并且返回-2
}
memcpy(newnode->data, data, handler->size);//拷贝数据

switch(mode)
{
case HEADINSERT : break;
case TAILINSERT : p = p->prev; break;
default : free(newnode->data); free(newnode);
return -3;
}
newnode->next = p->next;
newnode->prev = p;
newnode->next->prev = newnode;
newnode->prev->next = newnode;
return 0;
}

void llist_display(LLIST *handler, llist_op op)
{
struct llist_node *cur = NULL;
for(cur=handler->head.next;cur!=&handler->head;cur=cur->next)
op(cur->data);
}

void llist_destroy(LLIST *handler)
{
struct llist_node *cur = NULL;

for(cur=handler->head.next;cur!=&handler->head;cur=handler->head.next)
{
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur->data);
free(cur);
}
free(handler);
}

struct llist_node *_find(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

for(cur=handler->head.next;cur!=&handler->head;cur=cur->next)
if(cmp(cur->data, find_data))
return cur;
return NULL;
}

void *llist_find(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

cur = _find(handler, find_data, cmp);
if(cur == NULL)
return NULL;
return cur->data;
}

int llist_delete(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

cur = _find(handler, find_data, cmp);
if(cur == NULL)
return -1;
///////cur指针已经指向要删除的结点
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur->data);
free(cur);
return 0;
}

int llist_fetch(LLIST *handler, const void *find_data, llist_cmp cmp, void *save)
{
struct llist_node *cur = NULL;

cur = _find(handler,find_data,cmp);
if(cur == NULL)
return -1;

cur->next->prev = cur->prev;
cur->prev->next = cur->next;
memcpy(save, cur->data, handler->size);
free(cur->data);
free(cur);

return 0;
}

makefile

1
2
3
4
llist : main.o llist.o
gcc -o $@ $^
clean :
rm -rf *.o llist

可变长的通用性强的链表

=================================

可变长的结构体

        需要把可变长的因子放到结构体定义的最后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdlib.h>

struct aaa
{
void *data;
struct aaa *prev;
struct aaa *next;
};

struct bbb
{
struct bbb *prev;
struct bbb *next;
char data[0];
};

int main(int argc, char *argv[])
{
struct bbb *newnode = NULL;

printf("sizeof(struct aaa) = %ld\n", sizeof(struct aaa));
printf("sizeof(struct bbb) = %ld\n", sizeof(struct bbb));

//newnode = malloc(sizeof(struct bbb));//开辟16byte空间
newnode = malloc(sizeof(struct bbb) + 40);//开辟56byte空间

return 0;
}
=================================

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdio.h>
#include <string.h>
#include "llist.h"

#define NAMESIZE 20//字符数组的成员个数

struct stu//客户自己创建的数据结构体
{
int id;
char name[NAMESIZE];
int math;
int age;
int tel;
};

void print(const void *data)
{
const struct stu *p = data;
printf("%d %s %d %d %d\n",p->id,p->name,p->math,p->age, p->tel);
}

int id_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const int *k = key;

return !(p->id - *k);
}

int name_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const char *k = key;

return !(strcmp(p->name, k));
}

int tel_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const int *k = key;

return !(p->tel - *k);
}

int main(void)
{
LLIST *handler = NULL;//handler指针指向头结点
struct stu data;//存放客户自己的数据
struct stu save;//存储拿出的数据
struct stu *find = NULL;//指向找到的数据
int i = 0;//循环变量
int ret = 0;//接收返回值
int find_id = 100;
int find_tel = 10002;
char *find_name = "stu4";

handler = llist_create(sizeof(struct stu));
//创建头结点
if(handler == NULL)//判断头结点是否创建失败
return -1;//创建失败,结束程序,并且返回-1

for(i = 0; i < 5; i++)
{
data.id = 100 + i;//存储数据
sprintf(data.name, "stu%d", i);//存储数据
data.math = 100 - i;//存储数据
data.age = 20 + i;//存储数据
data.tel = 10000 + i;//存储数据
llist_insert(handler,&data,TAILINSERT);//插入数据
}

llist_display(handler, print);//遍历链表

printf("============================\n");
/*
find = llist_find(handler, &find_tel, tel_cmp);//查找
if(find == NULL)//判断是否没有找到
printf("Not Find It!\n");
else
{
printf("Find It!\n");
print(find);
}
*/
#if 0
ret = llist_delete(handler, &find_tel, tel_cmp);
if(ret != 0)
printf("Delete It Is Failed!\n");
else
printf("Delete It!\n");
#else
ret = llist_fetch(handler, &find_tel, tel_cmp, &save);
if(ret != 0)
printf("Fetch It Is Failed!\n");
else
{
printf("Fetch It!\n");
print(&save);
}
#endif

printf("============================\n");

llist_display(handler, print);//遍历链表

llist_destroy(handler);//销毁链表

return 0;
}

llist.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef __LLIST_H
#define __LLIST_H

#define HEADINSERT 0
#define TAILINSERT 1

typedef void (*llist_op)(const void *);//定义函数指针类型
typedef int (*llist_cmp)(const void *,const void *);

struct llist_node//数据结点的结构体(可变长的结构体)
{
struct llist_node *prev;//prev指针指向前驱
struct llist_node *next;//next指针指向后继
char data[0];//可变长的因子
};

typedef struct llist_head//头结点的结构体
{
int size;//保存客户创建的结构体的大小
struct llist_node head;//
}LLIST;

LLIST *llist_create(int );//创建头结点

int llist_insert(LLIST *, const void *, int );//插入数据

void llist_display(LLIST *, llist_op);//遍历链表

void llist_destroy(LLIST *);//销毁链表

void *llist_find(LLIST *, const void *, llist_cmp);//查找

int llist_delete(LLIST *, const void *, llist_cmp);//删除

int llist_fetch(LLIST *, const void *, llist_cmp, void *);

#endif

llist.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "llist.h"

LLIST *llist_create(int size)
{
LLIST *handler = NULL;//指向头结点的指针

handler = malloc(sizeof(LLIST));//为头结点开辟空间
if(handler == NULL)//判断头结点空间是否开辟失败
return NULL;//开辟失败,结束函数,并且返回NULL
handler->size = size;//把客户结构体大小存储起来
handler->head.prev = &handler->head;//前驱指向自己
handler->head.next = &handler->head;//后继指向自己
return handler;//把指向头结点的指针返回
}

int llist_insert(LLIST *handler,const void *data,int mode)
{
struct llist_node *p = &handler->head;//保存头结点地址
struct llist_node *newnode = NULL;//保存新建的数据结点

newnode = malloc(sizeof(struct llist_node) + handler->size);//数据结点
if(newnode == NULL)//判断数据结点是否开辟失败
return -1;//开辟失败,结束函数,并且返回-1

memcpy(newnode->data, data, handler->size);//拷贝数据

switch(mode)
{
case HEADINSERT : break;
case TAILINSERT : p = p->prev; break;
default : free(newnode); return -3;
}
newnode->next = p->next;
newnode->prev = p;
newnode->next->prev = newnode;
newnode->prev->next = newnode;
return 0;
}

void llist_display(LLIST *handler, llist_op op)
{
struct llist_node *cur = NULL;
for(cur=handler->head.next;cur!=&handler->head;cur=cur->next)
op(cur->data);
}

void llist_destroy(LLIST *handler)
{
struct llist_node *cur = NULL;

for(cur=handler->head.next;cur!=&handler->head;cur=handler->head.next)
{
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur);
}
free(handler);
}

struct llist_node *_find(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

for(cur=handler->head.next;cur!=&handler->head;cur=cur->next)
if(cmp(cur->data, find_data))
return cur;
return NULL;
}

void *llist_find(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

cur = _find(handler, find_data, cmp);
if(cur == NULL)
return NULL;
return cur->data;
}

int llist_delete(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

cur = _find(handler, find_data, cmp);
if(cur == NULL)
return -1;
///////cur指针已经指向要删除的结点
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur);
return 0;
}

int llist_fetch(LLIST *handler, const void *find_data, llist_cmp cmp, void *save)
{
struct llist_node *cur = NULL;

cur = _find(handler,find_data,cmp);
if(cur == NULL)
return -1;

cur->next->prev = cur->prev;
cur->prev->next = cur->next;
memcpy(save, cur->data, handler->size);
free(cur);

return 0;
}

makefile

1
2
3
4
llist : main.o llist.o
gcc -o $@ $^
clean :
rm -rf *.o llist
=================================

封装通用性强的链表

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdio.h>
#include <string.h>
#include "llist.h"

#define NAMESIZE 20//字符数组的成员个数

struct stu//客户自己创建的数据结构体
{
int id;
char name[NAMESIZE];
int math;
int age;
int tel;
};

void print(const void *data)
{
const struct stu *p = data;
printf("%d %s %d %d %d\n",p->id,p->name,p->math,p->age, p->tel);
}

int id_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const int *k = key;

return !(p->id - *k);
}

int name_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const char *k = key;

return !(strcmp(p->name, k));
}

int tel_cmp(const void *data, const void *key)
{
const struct stu *p = data;
const int *k = key;

return !(p->tel - *k);
}

int main(void)
{
LLIST *handler = NULL;//handler指针指向头结点
struct stu data;//存放客户自己的数据
struct stu save;//存储拿出的数据
struct stu *find = NULL;//指向找到的数据
int i = 0;//循环变量
int ret = 0;//接收返回值
int find_id = 100;
int find_tel = 10002;
char *find_name = "stu4";

handler = llist_create(sizeof(struct stu));
//创建头结点
if(handler == NULL)//判断头结点是否创建失败
return -1;//创建失败,结束程序,并且返回-1

for(i = 0; i < 5; i++)
{
data.id = 100 + i;//存储数据
sprintf(data.name, "stu%d", i);//存储数据
data.math = 100 - i;//存储数据
data.age = 20 + i;//存储数据
data.tel = 10000 + i;//存储数据
llist_insert(handler,&data,TAILINSERT);//插入数据
}

llist_display(handler, print);//遍历链表

printf("============================\n");
/*
find = llist_find(handler, &find_tel, tel_cmp);//查找
if(find == NULL)//判断是否没有找到
printf("Not Find It!\n");
else
{
printf("Find It!\n");
print(find);
}
*/
#if 0
ret = llist_delete(handler, &find_tel, tel_cmp);
if(ret != 0)
printf("Delete It Is Failed!\n");
else
printf("Delete It!\n");
#else
ret = llist_fetch(handler, &find_tel, tel_cmp, &save);
if(ret != 0)
printf("Fetch It Is Failed!\n");
else
{
printf("Fetch It!\n");
print(&save);
}
#endif

printf("============================\n");

llist_display(handler, print);//遍历链表

llist_destroy(handler);//销毁链表

return 0;
}

llist.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef __LLIST_H
#define __LLIST_H

#define HEADINSERT 0
#define TAILINSERT 1

typedef void (*llist_op)(const void *);//定义函数指针类型
typedef int (*llist_cmp)(const void *,const void *);
typedef void LLIST;

LLIST *llist_create(int );//创建头结点

int llist_insert(LLIST *, const void *, int );//插入数据

void llist_display(LLIST *, llist_op);//遍历链表

void llist_destroy(LLIST *);//销毁链表

void *llist_find(LLIST *, const void *, llist_cmp);//查找

int llist_delete(LLIST *, const void *, llist_cmp);//删除

int llist_fetch(LLIST *, const void *, llist_cmp, void *);

#endif

llist.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "llist.h"

struct llist_node//数据结点的结构体(可变长的结构体)
{
struct llist_node *prev;//prev指针指向前驱
struct llist_node *next;//next指针指向后继
char data[0];//可变长的因子
};

struct llist_head//头结点的结构体
{
int size;//保存客户创建的结构体的大小
struct llist_node head;//
};

LLIST *llist_create(int size)
{
struct llist_head *handler = NULL;//指向头结点的指针

handler = malloc(sizeof(LLIST));//为头结点开辟空间
if(handler == NULL)//判断头结点空间是否开辟失败
return NULL;//开辟失败,结束函数,并且返回NULL
handler->size = size;//把客户结构体大小存储起来
handler->head.prev = &handler->head;//前驱指向自己
handler->head.next = &handler->head;//后继指向自己
return handler;//把指向头结点的指针返回
}

int llist_insert(LLIST *h,const void *data,int mode)
{
struct llist_head *handler = h;
struct llist_node *p = &handler->head;//保存头结点地址
struct llist_node *newnode = NULL;//保存新建的数据结点

newnode = malloc(sizeof(struct llist_node) + handler->size);//数据结点
if(newnode == NULL)//判断数据结点是否开辟失败
return -1;//开辟失败,结束函数,并且返回-1

memcpy(newnode->data, data, handler->size);//拷贝数据

switch(mode)
{
case HEADINSERT : break;
case TAILINSERT : p = p->prev; break;
default : free(newnode); return -3;
}
newnode->next = p->next;
newnode->prev = p;
newnode->next->prev = newnode;
newnode->prev->next = newnode;
return 0;
}

void llist_display(LLIST *h, llist_op op)
{
struct llist_head *handler = h;
struct llist_node *cur = NULL;
for(cur=handler->head.next;cur!=&handler->head;cur=cur->next)
op(cur->data);
}

void llist_destroy(LLIST *h)
{
struct llist_head *handler = h;
struct llist_node *cur = NULL;

for(cur=handler->head.next;cur!=&handler->head;cur=handler->head.next)
{
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur);
}
free(handler);
}

struct llist_node *_find(LLIST *h, const void *find_data, llist_cmp cmp)
{
struct llist_head *handler = h;
struct llist_node *cur = NULL;

for(cur=handler->head.next;cur!=&handler->head;cur=cur->next)
if(cmp(cur->data, find_data))
return cur;
return NULL;
}

void *llist_find(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

cur = _find(handler, find_data, cmp);
if(cur == NULL)
return NULL;
return cur->data;
}

int llist_delete(LLIST *handler, const void *find_data, llist_cmp cmp)
{
struct llist_node *cur = NULL;

cur = _find(handler, find_data, cmp);
if(cur == NULL)
return -1;
///////cur指针已经指向要删除的结点
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur);
return 0;
}

int llist_fetch(LLIST *h, const void *find_data, llist_cmp cmp, void *save)
{
struct llist_head *handler = h;
struct llist_node *cur = NULL;

cur = _find(handler,find_data,cmp);
if(cur == NULL)
return -1;

cur->next->prev = cur->prev;
cur->prev->next = cur->next;
memcpy(save, cur->data, handler->size);
free(cur);

return 0;
}

makefile

1
2
3
4
llist : main.o llist.o
gcc -o $@ $^
clean :
rm -rf *.o llist