• 纯C语言(C89)实现简单链表


    起因

    工作很少接触纯C项目,业余写着玩玩,不断雕琢

    目标

    纯C实现简单链表,提供方便易用泛型接口,避免依赖

    实现

    完全封装,隐藏结构体细节,不支持栈创建
    拷贝存储,轻微性能代价换来易用性

    list.h

    #ifndef LIST_H
    #define LIST_H
    #include <stddef.h>
    
    typedef struct ListItem_ ListItem;
    typedef struct List_ List;
    
    extern     List* list_new();
    extern      void list_free(List* l);
    extern    size_t list_length(List* l);
    extern ListItem* list_head(List* l);
    extern ListItem* list_tail(List* l);
    extern ListItem* list_next(ListItem* e);
    extern    size_t list_data(ListItem* e, void** data);
    extern       int list_insert_next(List* l, ListItem* e, void* data_in, size_t size);
    extern       int list_remove_next(List* l, ListItem* e);
    
    #endif // LIST_H
    

    list.c

    #include "list.h"
    #include <stdlib.h>
    #include <string.h>
    
    typedef unsigned char byte;
    
    typedef struct ListItem_ {
    	struct ListItem_* next;
    	byte* data;
    	size_t size;
    } ListItem;
    
    typedef struct List_ {
    	size_t count;
    	ListItem* head;
    	ListItem* tail;
    } List;
    
    List* list_new() {
    	List* l = calloc(1, sizeof(List));
    	return l;
    }
    
    void list_free(List* l) {
    	while (list_length(l) > 0) {
    		list_remove_next(l, 0);
    	}
    }
    
    size_t list_length(List* l) {
    	return l->count;
    }
    
    ListItem* list_head(List* l) {
    	return l->head;
    }
    
    ListItem* list_tail(List* l) {
    	return l->tail;
    }
    
    ListItem* list_next(ListItem* e) {
    	return e->next;
    }
    
    size_t list_data(ListItem* e, void** data) {
    	if (!e) return 0;
    	*data = e->data;
    	return e->size;
    }
    
    int list_insert_next(List* l, ListItem* e, void* data_in, size_t size) {
    	ListItem* e_new = calloc(1, sizeof(ListItem));
    	if (!e_new) return -1;
    	e_new->data = calloc(size, sizeof(byte));
    	if (e_new->data) {
    		memcpy(e_new->data, data_in, size);
    		e_new->size = size;
    	} else {
    		free(e_new);
    		return -1;
    	}
    	if (l->count == 0) {
    		if (e) return -1;
    		l->head = e_new;
    		l->tail = e_new;
    	} else if (e) {
    		e_new->next = e->next;
    		e->next = e_new;
    		if (!e_new->next) 
    			l->tail = e_new;
    	} else {
    		e_new->next = l->head;
    		l->head = e_new;	
    	}
    	l->count ++;
    	return 0;
    }
    
    int list_remove_next(List* l, ListItem* e) {
    	ListItem* e_next;
    	if (l->count == 0) return -1;
    	if (e) {
    		if (!e->next) return -1;
    		e_next = e->next;
    		e->next = e_next->next;
    	} else {
    		e_next = l->head;
    		l->head = e_next->next;
    		if (l->count == 1) l->tail = 0;
    	}
    	free(e_next->data);
    	free(e_next);
    	l->count --;
    	return 0;
    }
    

    测试

    #include <stdio.h>
    #include <stdlib.h>
    #include "list.h"
    
    int main(int argc, char *argv[]) {
    	List* l = list_new();
    	ListItem* it;
    	size_t l_len = 0;
    	int i, x, y, *p, n;
    	for (i=0; i<10; i++) {
    		list_insert_next(l,0,&i,sizeof(i));
    	}
    	l_len = list_length(l);
    	printf("l_len:%d 
    ", l_len);
    	while (list_length(l) > 0) {
    		if (!list_remove_next(l,0)) {
    			n = list_data(list_head(l), &p);
    			if (n) printf("list_head:%d size:%d 	", *p, n);
    			n = list_data(list_tail(l), &p);
    			if (n) printf("list_tail:%d size:%d 
    ", *p, n);		
    		}
    	}
    	list_free(l);
    	return 0;
    }
    
    l_len:10
    list_head:8 size:4      list_tail:0 size:4
    list_head:7 size:4      list_tail:0 size:4
    list_head:6 size:4      list_tail:0 size:4
    list_head:5 size:4      list_tail:0 size:4
    list_head:4 size:4      list_tail:0 size:4
    list_head:3 size:4      list_tail:0 size:4
    list_head:2 size:4      list_tail:0 size:4
    list_head:1 size:4      list_tail:0 size:4
    list_head:0 size:4      list_tail:0 size:4
    
  • 相关阅读:
    EXT FileUploadField 文件上传失败
    CRM自定义页面
    The report server was unable to validate the integrity of encrypted data in the database. (rsCannotValidateEncryptedData) .
    sql存储过程与临时表
    MERGE INTO
    [LeetCode]Merge Two Sorted Lists
    [LeetCode]Search for a Range
    [LeetCode]Length of Last Word
    [LeetCode]Implement strStr()
    [LeetCode]Pascal's Triangle
  • 原文地址:https://www.cnblogs.com/wuyaSama/p/11546474.html
Copyright © 2020-2023  润新知