uthash是个可以在C语言上运行的哈希库,在 C 语言中,哈希值不会存在于语言本身中。该库为 C 语言提供了一个哈希表结构。
官方文档
下述是基于官方文档的部分介绍,基本了解下基本的用法。还有就是,案例程序的构造是按照官方的,就是部分数据的命名,我会按照键:值
(健值对)的思想来重新命名,而不是官方的用户和名称ID对。和uthash有关的链接:uthash的github链接,uthash用户指南
任何 C 结构都可以使用 uthash 存储在哈希表中。只需向结构中添加UT_hash_handle并选择一个或多个字段作为 key。然后使用这些宏来存储, 从哈希表中检索或删除项目。
-
将项目添加到哈希中。
#include "uthash.h" // 整型键结构 struct my_struct_int { int key; /* 我们将使用这个字段作为键 */ char value[10]; UT_hash_handle hh; /* 使这个结构可哈希 */ }; typedef struct my_struct_int hash_int_t; // 表头 hash_int_t *table = NULL; /* 简略版,添加键值对。与下面新的函数的区别是,没有对新输入键进行审核,否是已经存在。 uthash不会判断输入健值唯一性,需要用户在输入时,自行保证。 void Hash_addIntKey(hash_int_t *s) { HASH_ADD_INT( table, key, s ); } */ void Hash_addIntKey(int intKey, char *value) { hash_int_t *s; HASH_FIND_INT(table, &intKey, s); /* id已经在散列中了吗? */ if (s == NULL) { s = (hash_int_t *)malloc(sizeof *s); s->key = intKey; HASH_ADD_INT(table, key, s); /* id:关键字段的名称 */ } strcpy(s->value, value); }
-
在 hash 中查找项目。
hash_int_t *Hash_findIntKey(int intKey) { hash_int_t *s; HASH_FIND_INT( table, &intKey, s ); return s; }
-
从哈希中删除项目。假如创建键值对时,是通过在函数中输入键和值,没有存储该键值对的句柄时,可以通过
HASH_FIND_INT
先重新寻找到,在把句柄传递删除。void Hash_deleteIntKey(hash_int_t *intKey) { HASH_DEL( table, intKey); }
-
主函数中的代码
int main() { Hash_addIntKey(123,"Hi"); printf("val:%s\r\n",Hash_findIntKey(123)->value); return 0; }
不同的密钥类型
相对于演示的整数键来说,其它不同的密钥类型会在宏和键结构上有所变化。下述就在举例字符串键
,在对比整数键后,可基本了解差异化在哪里,在理解起其它的指针键,结构键就能更快的理解和自行构造。
整数键
从前面的示例了整数键的使用,就可以看到使用到的相关宏为,HASH_ADD_INT
,HASH_FIND_INT
,HASH_DELETE
,HASH_SORT
。部分专有的宏,用来获取控制传入键类型的宏都会有,该类型的尾缀如整型的_INT
。
字符串键
直接在程序中理解,下述程序为笔者按照自己风格编写,可能和官方的介绍代码中的书写风格有所不同。
// 字符串键结构
struct my_struct_str{
char key[10]; /* 键 */
int value;
UT_hash_handle hh; /* 使这个结构可哈希 */
};
typedef struct my_struct_str hash_str_t;
// 表头
hash_str_t *table = NULL;
// 添加键
void Hash_addStrKey(char *strKey,int val)
{
hash_str_t *s = NULL;
HASH_FIND_STR(table, strKey, s);
if(s == NULL)
{
s = (hash_str_t *)malloc(sizeof *s);
strcpy(s->key, strKey);
HASH_ADD_STR(table, key, s);
}
s->value = val;
}
// 查找键
hash_str_t *Hash_findStrKey(char *strKey)
{
hash_str_t *s = NULL;
HASH_FIND_STR(table, strKey, s);
return s;
}
// main函数中内容
int main() {
hash_str_t *s;
Hash_addStrKey("apple",150);
s = Hash_findStrKey("apple");
printf("val:%d\r\n",s->value);
return 0;
}
总结
通过上述案例,应该能了解到基本使用方法。导入库,定义键值对结构体,创建表头(全局哈希句柄),在基于宏构建出添加,查找,删除。要查看更加详细的信息可以查看uthash用户指南。下述是其它事项:
- uthash只是一个头文件,没有链接到其它库的代码(除了C语言自带的库),因此在使用时只需
#include "uthash.h"
即可,其它拉取来的其它文件都是额外的内容。 - 唯一键。与任何哈希一样,每个项目都必须具有唯一键。您的应用程序必须强制实施密钥唯一性。在将项目添加到哈希表之前,您必须首先知道(如有疑问,请检查)密钥尚未被使用。可以使用
HASH_FIND
检查哈希表中是否已存在 key。
附上uthash的项目github文件,库在\src
下。拉取日期为2024/9/1。
链接:https://pan.baidu.com/s/1FECbFPtSJJqpUUkqPUjKcA 提取码:nmdz