C语言 实现双向链表

发布时间 2023-12-12 22:17:19作者: 王景迁
#include <stdio.h>

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define list_for_each_entry(obj, head, list) for (obj = (typeof(*obj) *)((char *)((&head)->next) - (char *) &((typeof(*obj) *)0)->list); &obj->list != (&head); obj = (typeof(*(obj)) *)((char *)((obj)->list.next) - (char *) &((typeof(*(obj)) *)0)->list))

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

struct student {
    // 通过相对偏移量可以计算所在结构体首地址
    struct list_head list;
    int age;
};

struct list_head students = LIST_HEAD_INIT(students);

void list_add(struct list_head *new, struct list_head *head) {
    struct list_head* prev = head;
    struct list_head* next = head->next;
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

void list_del(struct list_head *entry) {
    struct list_head* prev = entry->prev;
    struct list_head* next = entry->next;
    next->prev = prev;
    prev->next = next;
}

void add_student(struct student* s) {
    // 把list插入到students后面
    list_add(&s->list, &students);
}

void del_student(struct student* s) {
    list_del(&s->list);
}

void print_all_students_age() {
    struct student* s;
    list_for_each_entry(s, students, list) {
        printf(" %d", s->age);
    }
    printf("\n");
}

int main() {
    struct student s1 = {.age = 16};
    struct student s2 = {.age = 17};
    struct student s3 = {.age = 18};

    add_student(&s1);
    add_student(&s2);
    add_student(&s3);
    print_all_students_age();

    del_student(&s2);
    print_all_students_age();

    return 0;
}