凤凰平台注册开户_凤凰彩票app下载安装_凤凰彩票投注网

热门关键词: 凤凰平台注册开户,凤凰彩票app下载安装,凤凰彩票投注网

凤凰彩票app下载安装:c语言泛型,c语言是什么样

作者: 编程知识  发布:2019-09-24

  近些日子有看一点Linux内核源码,开采根本里多量利用了list_head结构体。百度查了一下,原本基本金和利息用这几个结构体达成了泛型。

c语言是什么样完成泛型链表,c语言泛型

  最近有看一点Linux内核源码,开采基本里大批量利用了list_head结构体。百度查了一晃,原本基本金和利息用那一个结构体实现了泛型。

  自以为对链表已经很熟识的本人,决定自个儿完成一下。

  下面以Node和list_head为例。

凤凰彩票app下载安装 1

  上海体育场合正是循环链大致思路了。(画的不得了)

  大家透过list_head对链表进行活动操作。

  这里存在多少个难题:

    首先通过list_head获得的指针,它指向的list_head的结构体,但大家实在想要使用的是Node结构体。

    再有,大家要规划贰个泛型的链表,那么,小编就不能在落到实处链表时有任何对Node的操作。

  消除办法:

    1、通过估测计算,找到node结构体的首地址。(大家通过叁个宏来实现)

1 #define list_entry(ptr, type, member) 
2     ((type *)((char *)(ptr) - (char *)(&(((type *)0)->member))))

    那么些宏看起来或许点乱,但大家把思路缕清就不乱了。

凤凰彩票app下载安装 2

小编们只明白entry的指针,怎样求出Node的指针呢?

一旦大家能够理解entry的对峙地点,那么

  Node的莫过于地点  = entry的其实地方 - entry的相对地方。

  entry的绝对地方 =  (&(((Node *)0)->entry))   又蒙了么?  这里,我们先将 0转变为(Node *)类型的指针,再用那一个指针指向entry,最后取它的地点。那时我们就获得了entry的相对地点。

  宏中把他们强转成char * 是为了扩充减法。最终再强转成Node类型,那时小编就拿到了Node的指针。

2、让客商自身定义特定数据的操作,大家只提供四个函数接口(我们经过函数指针来达成)

  在大家的链表里,只涉及到了list_head 里的源委,所以,不能够对Node进行操作。参数也都以list_head的指针。那就必要顾客在接纳时,通过地点的宏来达成从list_head 到 Node的调换。在稍后例子中会精通到。

 

源码

dclist_head.h

 1 /*************************************************************************
 2     > File Name: dlist_head.h
 3     > Author: gaozy
 4     > Mail: [email protected] 
 5     > Created Time: 2016年12月24日 星期六 10时11分22秒
 6  ************************************************************************/
 7 
 8 /*
 9  *这是我自己实现的一个泛型循环链表
10  *使用者只需要把dclist_head_t 这个结构体加入到自己的结构体中就可以使用这个链表了。
11  *在使用时,需要使用者创建一个头节点,之后使用init函数初始化。(当然,你也可以自己对他进行初始化操作)
12  *它很重要,否则无法使用这个链表。
13  *链表给使用者提供了四个函数
14  *init 刚刚已经说过了,我们用它初始化链表
15  *append 这是一个向链表中添加节点的函数,需要我们传入链表的头和新节点的dclist_head_t部分的指针
16  *treaverse 正如火函数名一样,它的作用是遍历链表,它需要我们提供一个函数指针
17  *这个指针的作用是对节点进行操作,参数是一个dclist_head_t 类型的指针,我们同过list_entry这个宏获取
18  *使用者自定义的数据类型。
19  *dc_remove这个函数用来释放链表,类似treaverse函数,需要我们自己实现删除j节点函数。
20  *它会释放链表中的所有节点,只有头结点例外,头需要我们自己释放
21  */
22 
23 #ifndef DLIST_HEAD
24 #define    DLIST_HEAD
25 
26 #define list_entry(ptr, type, member) 
27     ((type *)((char *)(ptr) - (char *)(&(((type *)0)->member))))
28 
29 typedef struct dclist_head {
30     struct dclist_head * prev;
31     struct dclist_head * next;
32 } dclist_head_t;
33 
34 void init(dclist_head_t *head);
35 void append(dclist_head_t *head, dclist_head_t *node);
36 void treaverse(dclist_head_t *head, void (*pfun)(dclist_head_t *node) );
37 void dc_remove(dclist_head_t *head, void (*pfun)(dclist_head_t *node) );
38 
39 #endif

dclist_head.c

 1 /*************************************************************************
 2     > File Name: dclist_head.c
 3     > Author: gaozy
 4     > Mail: [email protected] 
 5     > Created Time: 2016年12月24日 星期六 10时19分49秒
 6  ************************************************************************/
 7 
 8 #include <stdio.h>
 9 #include <stdlib.h>
10 
11 #include "dclist_head.h"
12 
13 
14 void init(dclist_head_t *head)
15 {
16     if ( head != NULL ) {
17         head->prev = NULL;
18         head->next = NULL;
19     }
20 }
21 
22 void append(dclist_head_t *head, dclist_head_t *node)
23 {
24     if ( head == NULL ) {
25         printf("errorn");
26         exit(1);
27     }
28 
29     if ( head->prev == NULL && head->next == NULL ) {
30         head->prev = node;
31         head->next = node;
32         node->prev = head;
33         node->next = head;
34     } else {
35         dclist_head_t *tmp = head->prev;
36         tmp->next = node;
37         node->prev = tmp;
38         node->next = head;
39         head->prev = node;
40     }
41 }
42 
43 void treaverse(dclist_head_t *head, void (*pfun)(dclist_head_t *node) )
44 {
45     if ( head == NULL || head->next == NULL )
46         return;
47 
48     dclist_head_t *tmp = head->next;
49     while ( tmp != head ) {
50         pfun(tmp);
51         tmp = tmp->next;
52     }
53 }
54 
55 void dc_remove(dclist_head_t *head, void (*pfun)(dclist_head_t *node) )
56 {
57     treaverse(head, pfun);
58 }

测量试验代码

main.c

 1 /*************************************************************************
 2     > File Name: main.c
 3     > Author: gaozy
 4     > Mail: [email protected] 
 5     > Created Time: 2016年12月24日 星期六 11时11分25秒
 6  ************************************************************************/
 7 
 8 #include <stdio.h>
 9 #include <stdlib.h>
10 
11 #include "dclist_head.h"
12 
13 typedef struct {
14     int id;
15     dclist_head_t entry;
16 } student_t;
17 
18 void print(dclist_head_t *ptr)
19 {
20     student_t *stu = list_entry(ptr, student_t, entry);
21     if ( stu == NULL )
22         return;
23     printf("student id = %dn", stu->id);
24 }
25 
26 void free_node(dclist_head_t *ptr)
27 {
28     if (ptr == NULL )
29         return;
30     
31     student_t *node = list_entry(ptr, student_t, entry);
32     free(node);
33 }
34 
35 student_t* make_node(int id)
36 {
37     student_t *stu = (student_t *)malloc(sizeof(student_t));
38     if ( stu != NULL ) {
39         stu->id = id;
40     }
41 
42     return stu;
43 }
44 
45 int main(void)
46 {
47     dclist_head_t list;
48 
49     init(&list);
50 
51     int i;
52     student_t *stu;
53     for ( i=0; i<5; i++ ) {
54         stu = make_node(i);
55         if ( stu != NULL )
56             append(&list, &stu->entry);
57     }
58     
59 
60     treaverse(&list, print);
61     dc_remove(&list, free_node);
62 
63 
64     return 0;
65 }

水平有限,还请大神多多指导。

近日有看一点Linux内核源码,开掘根本里大批量运用了list_head结构体。百度查了一晃,原来基本金和利息用那...

  自感觉对链表已经很熟练的作者,决定本身完结一下。

  下面以Node和list_head为例。

凤凰彩票app下载安装 3

  上海教室正是循环链大约思路了。

  大家经过list_head对链表进行移动操作。

  这里存在多少个难题:

    首先通过list_head获得的指针,它指向的list_head的结构体,但我们实在想要使用的是Node结构体。

    再有,我们要统一希图七个泛型的链表,那么,笔者就不得以在贯彻链表时有任何对Node的操作。

  解决办法:

    1、通过计算,找到node结构体的首地址。(我们因而二个宏来完成)

1 #define list_entry(ptr, type, member) 2     ((char *) - (char *)(&0)->member))))

    这些宏看起来可能点乱,但大家把思路缕清就不乱了。

凤凰彩票app下载安装 4

作者们只知道entry的指针,怎么样求出Node的指针呢?

假使大家得以通晓entry的相对地方,那么

  Node的其实地点 = entry的实在地方 - entry的相持地点。

  entry的对峙地点 = (&0)->entry)) 又蒙了么? 这里,我们先将 0调换为品种的指针,再用那几个指针指向entry,最终取它的地点。那时大家就拿走了entry的对峙地方。

  宏中把他们强转成char * 是为着举办减法。最后再强转成Node类型,那时作者就收获了Node的指针。

2、让顾客本人定义特定数据的操作,大家只提供一个函数接口(我们通过函数指针来贯彻)

  在我们的链表里,只提到到了list_head 里的开始和结果,所以,不能够对Node实行操作。参数也都以list_head的指针。那就需求客商在利用时,通过上边的宏来达成从list_head 到 Node的调换。在稍后例子中会理解到。

源码

dclist_head.h

 1 /************************************************************************* 2     > File Name: dlist_head.h 3     > Author: gaozy 4     > Mail: 44523253@qq.com  5     > Created Time: 2016年12月24日 星期六 10时11分22秒 6  ************************************************************************/ 7  8 /* 9  *这是我自己实现的一个泛型循环链表10  *使用者只需要把dclist_head_t 这个结构体加入到自己的结构体中就可以使用这个链表了。11  *在使用时,需要使用者创建一个头节点,之后使用init函数初始化。(当然,你也可以自己对他进行初始化操作)12  *它很重要,否则无法使用这个链表。13  *链表给使用者提供了四个函数14  *init 刚刚已经说过了,我们用它初始化链表15  *append 这是一个向链表中添加节点的函数,需要我们传入链表的头和新节点的dclist_head_t部分的指针16  *treaverse 正如火函数名一样,它的作用是遍历链表,它需要我们提供一个函数指针17  *这个指针的作用是对节点进行操作,参数是一个dclist_head_t 类型的指针,我们同过list_entry这个宏获取18  *使用者自定义的数据类型。19  *dc_remove这个函数用来释放链表,类似treaverse函数,需要我们自己实现删除j节点函数。20  *它会释放链表中的所有节点,只有头结点例外,头需要我们自己释放21  */22 23 #ifndef DLIST_HEAD24 #define    DLIST_HEAD25 26 #define list_entry(ptr, type, member) 27     ((char *) - (char *)(&0)->member))))28 29 typedef struct dclist_head {30     struct dclist_head * prev;31     struct dclist_head * next;32 } dclist_head_t;33 34 void init(dclist_head_t *head);35 void append(dclist_head_t *head, dclist_head_t *node);36 void treaverse(dclist_head_t *head, void (dclist_head_t *node) );37 void dc_remove(dclist_head_t *head, void (dclist_head_t *node) );38 39 #endif

dclist_head.c

 1 /************************************************************************* 2     > File Name: dclist_head.c 3     > Author: gaozy 4     > Mail: 44523253@qq.com  5     > Created Time: 2016年12月24日 星期六 10时19分49秒 6  ************************************************************************/ 7  8 #include <stdio.h> 9 #include <stdlib.h>10 11 #include "dclist_head.h"12 13 14 void init(dclist_head_t *head)15 {16     if ( head != NULL ) {17         head->prev = NULL;18         head->next = NULL;19     }20 }21 22 void append(dclist_head_t *head, dclist_head_t *node)23 {24     if ( head == NULL ) {25         printf("errorn");26         exit(1);27     }28 29     if ( head->prev == NULL && head->next == NULL ) {30         head->prev = node;31         head->next = node;32         node->prev = head;33         node->next = head;34     } else {35         dclist_head_t *tmp = head->prev;36         tmp->next = node;37         node->prev = tmp;38         node->next = head;39         head->prev = node;40     }41 }42 43 void treaverse(dclist_head_t *head, void (dclist_head_t *node) )44 {45     if ( head == NULL || head->next == NULL )46         return;47 48     dclist_head_t *tmp = head->next;49     while ( tmp != head ) {50         pfun;51         tmp = tmp->next;52     }53 }54 55 void dc_remove(dclist_head_t *head, void (dclist_head_t *node) )56 {57     treaverse(head, pfun);58 }

测量试验代码

main.c

 1 /************************************************************************* 2     > File Name: main.c 3     > Author: gaozy 4     > Mail: 44523253@qq.com  5     > Created Time: 2016年12月24日 星期六 11时11分25秒 6  ************************************************************************/ 7  8 #include <stdio.h> 9 #include <stdlib.h>10 11 #include "dclist_head.h"12 13 typedef struct {14     int id;15     dclist_head_t entry;16 } student_t;17 18 void print(dclist_head_t *ptr)19 {20     student_t *stu = list_entry(ptr, student_t, entry);21     if ( stu == NULL )22         return;23     printf("student id = %dn", stu->id);24 }25 26 void free_node(dclist_head_t *ptr)27 {28     if (ptr == NULL )29         return;30     31     student_t *node = list_entry(ptr, student_t, entry);32     free;33 }34 35 student_t* make_node(int id)36 {37     student_t *stu = (student_t *)malloc(sizeof(student_t));38     if ( stu != NULL ) {39         stu->id = id;40     }41 42     return stu;43 }44 45 int main(void)46 {47     dclist_head_t list;48 49     init(&list);50 51     int i;52     student_t *stu;53     for ( i=0; i<5; i++ ) {54         stu = make_node;55         if ( stu != NULL )56             append(&list, &stu->entry);57     }58     59 60     treaverse(&list, print);61     dc_remove(&list, free_node);62 63 64     return 0;65 }

水平有限,还请大神多多指点。

本文由凤凰平台注册开户发布于编程知识,转载请注明出处:凤凰彩票app下载安装:c语言泛型,c语言是什么样

关键词:

上一篇:没有了
下一篇:常用模块,python常用模块