记录C语言实现的单向链表

发布时间 2023-11-11 20:08:01作者: -ssdq-

利用C语言实现的单向链表接口函数。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>



typedef void* OSMutex_t;

// duration: -1 forever; 0 no wait; n million seconds.
// return 0 if success.
static int OSMutex_lock(OSMutex_t mutex, int duration) {
    return 0;
}

static int OSMutex_unlock(OSMutex_t mutex) {
    return 0;
}

#if 1
static void node_print(void* data)  {
    printf("%d ", (int)data);
}

static int node_compare(void* src, void* target) {
    return (int)src - (int)target;
}

static void node_free_callback(void* data) {
    printf("free node, data is %d.\n", (int)data);
}
#endif


#if 1
struct snode {
    struct snode* next;
    void* data;
};


bool snode_append(struct snode** root, void* data, OSMutex_t mutex) {
    struct snode* node = malloc(sizeof(struct snode));
    if (NULL == node) {
        return false;
    }

    node->data = data;
    node->next = NULL;

    // -1: forever
    if (!OSMutex_lock(mutex, -1)) {
        while(*root) {
            root = &(*root)->next;
        }
        *root = node;
        OSMutex_unlock(mutex);
        return true;
    } else {
        free(node);
    }
    
    return false;
}

bool snode_insert_head(struct snode** root, void* data, OSMutex_t mutex) {
    struct snode* node = malloc(sizeof(struct snode));
    if (NULL == node) {
        return false;
    }

    node->data = data;

    // -1: forever
    if (!OSMutex_lock(mutex, -1)) {
        node->next = *root;
        *root = node;
        OSMutex_unlock(mutex);
        return true;
    } else {
        free(node);
    }
    
    return false;
}


bool snode_find_and_fetch(struct snode** root, int (*compare)(void* src, void* target), void* target, OSMutex_t mutex, void** pv) {
    struct snode* node = NULL;
    
    // -1: forever
    if (!OSMutex_lock(mutex, -1)) {
        while(*root) {
            if (!compare((*root)->data, target)) {
                node = *root;
                *root = node->next;
                node->next = NULL;
                break;
            }
            root = &(*root)->next;
        }
        OSMutex_unlock(mutex);
    }
    
    if (node) {
        *pv = node->data;
        free(node);
        return true;
    }
    
    return false;
}

bool snode_free_list(struct snode** root, void (*callback)(void* node), OSMutex_t mutex) {
    struct snode* head;
    struct snode* node;
    
    // -1: forever
    if (!OSMutex_lock(mutex, -1)) {
        head = *root;
        *root = NULL;
        OSMutex_unlock(mutex);
        
        while(head) {
            node = head;
            head = node->next;

            node->next = NULL;
            if (callback) {
                callback(node->data);
            }
            free(node);
        }

        return true;
    }
    
    return false;
}

void snode_display(struct snode** root, void (*print)(void* data), OSMutex_t mutex) {
    // -1: forever
    if (!OSMutex_lock(mutex, -1)) {
        while(*root) {
            print((*root)->data);
            root = &(*root)->next;
        }
        OSMutex_unlock(mutex);
    }
}

#endif


void test(void) {
    const int node_max = 10;
    struct snode* list = NULL;
    OSMutex_t mutex = NULL;
    
    for (int i=0; i<node_max; i++) {
        printf("append node-%d with value %d ", i, i);
        if (snode_append(&list, (void*)i, mutex)) {
            printf("success.\n");
        } else {
            printf("failed.\n");
        }
    }
    printf("node list is: ");
    snode_display(&list, node_print, mutex);
    printf("\n");
    
    void* data;
    for (int i=0; i<node_max; i++) {
        if (i&0x01) {
            printf("remove node-%d ", i); 
            if (snode_find_and_fetch(&list, node_compare, (void*)i, mutex, &data)) {
                printf("success, value=%d.\n", (int)data);
            } else {
                printf("failed.\n");
            }
        }
    }
    printf("node list is: ");
    snode_display(&list, node_print, mutex);
    printf("\n");
    
    printf("insert 99 at list head.\n");
    snode_insert_head(&list, (void*)99, NULL);
    printf("insert 88 at list head.\n");
    snode_insert_head(&list, (void*)88, NULL);
    printf("insert 77 at list head.\n");
    snode_insert_head(&list, (void*)77, NULL);
    printf("insert 66 at list head.\n");
    snode_insert_head(&list, (void*)66, NULL);
    printf("node list is: ");
    snode_display(&list, node_print, mutex);
    printf("\n");
    
    printf("free node list.\n");
    snode_free_list(&list, node_free_callback, mutex);
    printf("node list is: ");
    snode_display(&list, node_print, mutex);
    printf("\n");
    
    printf("finish\n");
}

int main(void) {
    test();
    getchar();
}

 

C:\Users\xx\Desktop>tcc.exe -run snode.c
append node-0 with value 0 success.
append node-1 with value 1 success.
append node-2 with value 2 success.
append node-3 with value 3 success.
append node-4 with value 4 success.
append node-5 with value 5 success.
append node-6 with value 6 success.
append node-7 with value 7 success.
append node-8 with value 8 success.
append node-9 with value 9 success.
node list is: 0 1 2 3 4 5 6 7 8 9
remove node-1 success, value=1.
remove node-3 success, value=3.
remove node-5 success, value=5.
remove node-7 success, value=7.
remove node-9 success, value=9.
node list is: 0 2 4 6 8
insert 99 at list head.
insert 88 at list head.
insert 77 at list head.
insert 66 at list head.
node list is: 66 77 88 99 0 2 4 6 8
free node list.
free node, data is 66.
free node, data is 77.
free node, data is 88.
free node, data is 99.
free node, data is 0.
free node, data is 2.
free node, data is 4.
free node, data is 6.
free node, data is 8.
node list is:
finish
测试输出

 

不能在中断服务函数里面调用这些接口。