C语言HashTable/HashSet库汇总

在https://stackoverflow.com/questions/1138742/looking-for-a-good-hash-table-implementation-in-c里介绍了很多个相关的库。经过个人筛选,综合考虑执行效率、文档完善程度、支持的数据类型三方面,选择了uthash
官方文档详见:http://troydhanson.github.io/uthash/userguide.html

*如果想当HashSet用,只需要value随便赋值即可

*如果只需要String类型的key和value,还可以考虑strmap

*之所以没选择python内置的libcfu(下载地址,官方文档),是因为它在Android的环境上编译时很多的问题。

简要范例 (详见官方文档)

1. 初始化

#include "uthash.h"

struct my_struct {
    int id; // key
    char name[10]; //value
    UT_hash_handle hh; // 必须有,让这个结构体hashable
};

struct my_struct *users = NULL; // 重要,必须初始化为NULL

2. 添加

void add_user(int user_id, char *name) {
    struct my_struct *s;
    HASH_FIND_INT(users, &user_id, s);  
    if (s == NULL) {
      s = (struct my_struct *)malloc(sizeof *s);
      s->id = user_id;
      HASH_ADD_INT(users, id, s); // id: key的名字
    }
    strcpy(s->name, name);
}

3. 查找

struct my_struct *find_user(int user_id) {
    struct my_struct *s;
    HASH_FIND_INT(users, &user_id, s);
    return s;
}

4. 删除

void delete_user(struct my_struct *user) {
    HASH_DEL(users, user);
    free(user); //可选
}

注意事项

  1. 如果在Android/gcc编译时报fall-through between switch labels,则可以用pragma语句把uthash相关的代码括起来
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
// uthash相关代码
#pragma GCC diagnostic pop

其实还可以用__attribute__ ((fallthrough)); 但是实测没有pragma这种方法好。

  1. 如果编译时报padding struct 'struct UT_hash_table' with 4 bytes to align 'tail',可以按照https://github.com/troydhanson/uthash/issues/118#issue-223582662的回答,调整uthash.h中变量的顺序

  2. 如果要当HashSet用,可能也需要额外声明一个变量,不然可能会出padding的问题,报padding struct 'struct fd_struct' with 4 bytes to align 'hh',如下:

struct fd_struct {
    int fd; // key
    int padding; // 填充用,或者是char padding[10]之类的;
    UT_hash_handle hh;
};

你可能感兴趣的:(C语言HashTable/HashSet库汇总)