對於習慣了 C++ STL 和 Boost 的開發者,重拾 C 語言時最缺乏的就是現成的數據結構庫。sglib 是一個極輕量、僅含頭文件的 C 語言通用數據結構庫,提供鏈表、隊列、哈希表、紅黑樹等常用結構,無需編譯鏈接,直接包含頭文件即可使用,非常適合嵌入式或輕量級項目。
sglib 利用 C 語言宏實現「泛型」,通過傳入結構體類型、比較函數、指針字段名等參數,自動生成類型安全的操作函數。核心宏包括:
SGLIB_LIST_CONCAT:鏈表拼接SGLIB_LIST_ADD_IF_NOT_MEMBER:若不存在則添加SGLIB_LIST_DELETE:刪除節點SGLIB_LIST_FOREACH:遍歷鏈表#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "sglib.h"
// 定義節點結構
typedef struct _ip_mask_map {
int first; // IP 地址段
int second; // 掩碼
struct _ip_mask_map *next; // 必須命名為 next
} ip_mask_map, *pip_mask_map;
// 比較函數:返回 0 表示相等
int ipcomp(ip_mask_map *elem1, ip_mask_map *elem2) {
return (elem1->first == elem2->first && elem1->second == elem2->second) ? 0 : 1;
}
int main() {
ip_mask_map *head = NULL, *elem, *_member;
// 添加第一個節點
elem = malloc(sizeof(ip_mask_map));
elem->first = 1; elem->second = 100; elem->next = NULL;
SGLIB_LIST_CONCAT(ip_mask_map, head, elem, next);
// 添加第二個節點
elem = malloc(sizeof(ip_mask_map));
elem->first = 2; elem->second = 200; elem->next = NULL;
SGLIB_LIST_CONCAT(ip_mask_map, head, elem, next);
// 嘗試添加重複節點(自動去重)
elem = malloc(sizeof(ip_mask_map));
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 != NULL) free(elem); // 重複則釋放新分配內存
// 遍歷並釋放
for (elem = head; elem != NULL;) {
pip_mask_map tmp = elem;
printf("%d,%d\n", elem->first, elem->second);
elem = elem->next;
free(tmp);
}
return 0;
}
next 的指針字段(單鏈表)或 prev/next(雙鏈表)int (*)(T*, T*)prev 和 next,使用 SGLIB_DLIST_* 系列宏SGLIB_HASHED_CONTAINER 宏,支持 O(1) 查找left/right/color 字段,使用 SGLIB_RBTREE_* 宏SGLIB_ARRAY_* 宏實現二分查找、快速排序sglib 以「零依賴、純頭文件、宏實現泛型」的特點,成為 C 語言項目中快速引入高性能數據結構的理想選擇。掌握其宏參數規範與內存管理約定,即可在項目中高效使用鏈表、哈希、樹等結構,大幅減少重複造輪子的工作量。