首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言輕量級容器庫sglib實戰:單向鏈表、哈希表、排序與迭代器模式

     編輯:關於C

sglib簡介

sglib (Simple Generic Library) 是單頭文件、無依賴、基於宏的C語言通用數據結構庫。提供:單/雙向鏈表、哈希表、紅黑樹、排序數組、隊列、位圖等,代碼極簡(~2000行),適合嵌入式/內核/輕量級項目。

核心宏機制

通過結構體成員名稱字符串化實現泛型:

#define SGLIB_LIST_CONCAT(TYPE, HEAD, ELEM, NEXT_FIELD) \
    do { TYPE *_p = (HEAD); if (!_p) (HEAD) = (ELEM); \
         else { while (_p->NEXT_FIELD) _p = _p->NEXT_FIELD; \
                _p->NEXT_FIELD = (ELEM); } } while(0)

實戰:IP-掩碼映射鏈表

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sglib.h"

typedef struct ip_mask_map {
    int first;   // IP地址(簡化為int)
    int second;  // 掩碼
    struct ip_mask_map *next; // 鏈表指針字段
} ip_mask_map;

// 比較函數:用於去重/查找
int ipcomp(ip_mask_map *a, ip_mask_map *b) {
    return (a->first == b->first && a->second == b->second) ? 0 : 1;
}

// 定義鏈表操作宏展開
SGLIB_DEFINE_LIST_PROTOTYPES(ip_mask_map, next)
SGLIB_DEFINE_LIST_FUNCTIONS(ip_mask_map, next)

int main() {
    ip_mask_map *head = NULL, *elem, *member;

    // 插入三個節點
    elem = malloc(sizeof(*elem)); elem->first=1; elem->second=100; elem->next=NULL;
    SGLIB_LIST_CONCAT(ip_mask_map, head, elem, next);

    elem = malloc(sizeof(*elem)); elem->first=2; elem->second=200; elem->next=NULL;
    SGLIB_LIST_CONCAT(ip_mask_map, head, elem, next);

    // 嘗試插入重複項 -> 去重
    elem = malloc(sizeof(*elem)); elem->first=2; elem->second=200; elem->next=NULL;
    SGLIB_LIST_ADD_IF_NOT_MEMBER(ip_mask_map, head, elem, ipcomp, next, member);
    if (member) { printf("Duplicate found\n"); free(elem); }

    // 遍歷並釋放
    for (elem = head; elem; ) {
        ip_mask_map *tmp = elem;
        printf("%d,%d\n", elem->first, elem->second);
        elem = elem->next;
        free(tmp);
    }
    return 0;
}

常用容器宏速查

容器定義宏核心操作宏比較函數簽名
單向鏈表SGLIB_DEFINE_LIST_*(TYPE, NEXT_FIELD)CONCAT, ADD_IF_NOT_MEMBER, DELETE, FIND_MEMBERint cmp(TYPE*, TYPE*)
雙向鏈表SGLIB_DEFINE_DLIST_*(TYPE, NEXT, PREV)ADD, DELETE, CONCAT同上
哈希表SGLIB_DEFINE_HASHED_*(TYPE, HASH_FIELD, CMP_FUNC)ADD, DELETE, FIND哈希函數+比較函數
排序數組SGLIB_DEFINE_SORTED_ARRAY_*(TYPE, CMP_FUNC)ADD, DELETE, BINARY_SEARCH比較函數
紅黑樹SGLIB_DEFINE_RBTREE_*(TYPE, LEFT, RIGHT, COLOR, CMP_FUNC)ADD, DELETE, FIND比較函數

哈希表示例:字符串計數器

typedef struct { char *key; int count; } counter;
unsigned counter_hash(counter *c) { return sglib_str_hash(c->key); }
int counter_cmp(counter *a, counter *b) { return strcmp(a->key, b->key); }

SGLIB_DEFINE_HASHED_CONTAINER(counter, 1024, hash_field, counter_cmp)
// 使用: counter *c; SGLIB_HASHED_CONTAINER_ADD(...)

優缺點評估

優點缺點
零依賴,單頭文件,極易集成宏展開難調試,編譯錯誤信息晦澀
無動態分配開銷(侵入式設計)侵入式:結構體必須包含指針字段
代碼極小,適合受限環境無迭代器抽象,遍歷需手寫循環
C89兼容,跨平台無問題功能有限,無高級算法(如圖、堆)

替代方案對比

  • uthash:專注哈希表,API更友好
  • klib/khash:高性能哈希/排序數組,單頭文件
  • C++ STL:若可用C++,優先選擇vector/unordered_map
  • GLib:功能全但依賴重,適合大型GTK項目
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved