/*从内核链表抽象模拟的小程序,体验另类结构体链表*/
#include "stdlib.h"
#include "stdio.h"
#include "string.h"

//指针结点
//暂时不使用,利用此结构体可作成动态链表
struct List
{
    struct List * prev,*next ;
};

//业务数据结点
struct Content
{
    char A[32];
    int B;
    char C[32];
    struct List ptr;
};

int main()
{

    struct Content t1;
    struct List *pCur = NULL;

    strcpy(t1.A , "willku")  ;
    t1.B = 88;
    strcpy(t1.C ,  "China") ;

    //取t1中的指针地址
    pCur = &(t1.ptr);
    //映射到0的位置从t1.ptr位置求偏移量(一个整数),得到该业务数据结点的地址
    struct Content *node = (struct Content *)((char *)pCur -
                ((size_t)&(((struct Content *)0)->ptr)));

    printf("A:%s\n", node->A);
    printf("B:%d\n", node->B);
    printf("C:%s\n", node->C);

    system("pause");
}


/*---------Begin-------内核list.h代码--------Begin-------------*/
#ifndef __C_LIST_H
#define __C_LIST_H

#define offsetof(TYPE, MEMBER)   ((size_t) &((TYPE *)0)->MEMBER)

/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:    the type of the container struct this is embedded in.
 * @member:    the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) (type *)((char *)ptr -offsetof(type,member))

/*
 * These are non-NULL pointers that will result in page faults
 * under normal circumstances, used to verify that nobody uses
 * non-initialized list entries.
 */
#define LIST_POISON1  ((void *) 0x00100100)
#define LIST_POISON2  ((void *) 0x00200200)

struct list_head {
    struct list_head *next, *prev;
};

/**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:    the type of the struct this is embedded in.
 * @member:    the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

static  void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

/**
 * list_for_each    -    iterate over a list
 * @pos:    the &struct list_head to use as a loop counter.
 * @head:    the head for your list.
 */
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

/**
 * list_for_each_r    -    iterate over a list reversely
 * @pos:    the &struct list_head to use as a loop counter.
 * @head:    the head for your list.
 */
#define list_for_each_r(pos, head) \
    for (pos = (head)->prev; pos != (head); pos = pos->prev)

/*
 * Insert a new entry between two known consecutive entries.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static  void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

/**
 * list_add - add a new entry
 * @new: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 */
static  void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}

/**
 * list_add_tail - add a new entry
 * @new: new entry to be added
 * @head: list head to add it before
 *
 * Insert a new entry before the specified head.
 * This is useful for implementing queues.
 */
static  void list_add_tail(struct list_head *new, struct list_head *head)
{
    __list_add(new, head->prev, head);
}

/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static  void __list_del(struct list_head * prev, struct list_head * next)
{
    next->prev = prev;
    prev->next = next;
}

/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty on entry does not return true after this, the entry is
 * in an undefined state.
 */
static  void list_del(struct list_head *entry)
{
    __list_del(entry->prev, entry->next);
    entry->next = LIST_POISON1;
    entry->prev = LIST_POISON2;
}

/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static  int list_empty(const struct list_head *head)
{
    return head->next == head;
}

static  void __list_splice(struct list_head *list,
                 struct list_head *head)
{
    struct list_head *first = list->next;
    struct list_head *last = list->prev;
    struct list_head *at = head->next;

    first->prev = head;
    head->next = first;

    last->next = at;
    at->prev = last;
}

/**
 * list_splice - join two lists
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static  void list_splice(struct list_head *list, struct list_head *head)
{
    if (!list_empty(list))
        __list_splice(list, head);
}

#endif // __C_LIST_H

/*---------End-------内核list.h代码--------End-------------*/

/*-----Begin-----利用内核list.h的简单实现.c-----Begin-------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "malloc.h"
#include "list.h"

/*
Linux内核为链表提供了一致的访问接口。
void INIT_LIST_HEAD(struct list_head *list);
void list_add(struct list_head *new, struct list_head *head);
void list_add_tail(struct list_head *new, struct list_head *head);
void list_del(struct list_head *entry);
int list_empty(const struct list_head *head);
*/

struct teacher_node {
    int     id;
    char    name;
    int     age;
    struct list_head list;
};

//栈上静态链表 仅学习语法
int main_stack()
{
    //链表结构
    struct list_head head, *plist;

    //业务数据结构(其中包含链表结构)
    struct teacher_node a, b;

    a.id = 2;
    b.id = 3;

    INIT_LIST_HEAD(&head);
    list_add(&a.list, &head);
    list_add(&b.list, &head);

    list_for_each(plist, &head) {
        struct teacher_node *node = list_entry(plist, struct teacher_node, list);
        printf("id = %d\n", node->id);
    }

    return 0;
}

//动态链表
struct list_head * main_creat()
{
    //链表头结点及辅助指针
    struct list_head *pHead = NULL, *pCur = NULL;

    //业务数据结构
    struct teacher_node  *pA = NULL, *pB = NULL;

    //创建链表头结点
    pHead =  (struct list_head *)malloc(sizeof(struct list_head));

    pA =  (struct teacher_node *)malloc(sizeof(struct teacher_node));
    pB =  (struct teacher_node *)malloc(sizeof(struct teacher_node));

    memset(pHead, 0, sizeof(struct list_head));

    memset(pA, 0, sizeof(struct teacher_node));
    memset(pB, 0, sizeof(struct teacher_node));

    pA->id = 20;
    pB->id = 30;

    //初始化头链表
    INIT_LIST_HEAD(pHead);

    //添加结点
    list_add(&pA->list, pHead);
    list_add(&pB->list, pHead);

    //遍历链表
    list_for_each(pCur, pHead) {
        struct teacher_node *node = list_entry(pCur, struct teacher_node, list);
    //list_entry(pCur, struct teacher_node, list)等价于
    //(struct teacher_node *)((char *)pCur  - ((size_t)&(((struct teacher_node *)0)->list))
        printf("id = %d\n", node->id);
    }
    return pHead;
}

int mainxx()
{
    struct list_head * head = NULL, *pCur = NULL;

    head = main_creat();
    if (head == NULL)
    {
        printf("func main_creat() err\n");
        return -1;
    }

    //遍历链表
    list_for_each(pCur, head) {
        struct teacher_node *node = list_entry(pCur, struct teacher_node, list);
        printf("id = %d\n", node->id);
    }
    getchar();
    getchar();
    return 0;
}

int main()
{
    main_stack();

    getchar();
    getchar();
    return 0;
}
/*-----End----利用内核list.h的简单实现.c-----End-------*/

备份地址: 【Linux内核链表学习