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)
#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_MEMBER | int 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兼容,跨平台無問題 | 功能有限,無高級算法(如圖、堆) |
vector/unordered_map