工做不多接觸純C項目,業餘寫着玩玩,不斷雕琢性能
純C實現簡單鏈表,提供方便易用泛型接口,避免依賴測試
徹底封裝,隱藏結構體細節,不支持棧建立
拷貝存儲,輕微性能代價換來易用性code
#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
#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 \n", 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 \t", *p, n); n = list_data(list_tail(l), &p); if (n) printf("list_tail:%d size:%d \n", *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