C语言uthash介绍
介绍
uthash是C语言比较优秀的开源代码。它实现了常见的hash操作函数,例如插入、查找、删除等。该套开源代码采用宏的方式实现hash函数的相关功能,支持C语言的任意数据结构最为key值,甚至可以采用多个值作为key,无论是自定义的struct还是基本数据类型,需要注意的是不同类型的key其操作接口方式略有不同。由于该代码采用宏的方式实现,所有的实现代码都在uthash.h文件中,因此只需要在自己的代码中包含"uthash.h"头文件即可。
uthash最初是Troy D. Hanson的个人使用方便的目标,放到了SourceForge,后来因为受欢迎下载量比较大,就放到了GitHub吧。
uthash是遵从BSD开源协议,可供个人、商业和组织自由使用。
hash操作
官方文档详细介绍了uthash的使用。这里提炼一些基本信息
https://troydhanson.github.io/uthash/userguide.html
定义hash结构体
在你定义的hash结构体中嵌入UT_hash_handle。在哈希表中是通过指针操作的,不会进行移动和复制,因此不必担心速度和内存问题。
#include "uthash.h"
struct my_struct {
int id; /* key */
char name[10];
UT_hash_handle hh; /* makes this structure hashable */
};
key的类型
uthash支持任意类型的key,包括整型、字符串、指针、结构体等。如果key类型不同,那么add和find函数有不同的接口,但是HASH_DELETE和HASH_SORT不区分key类型。
hash操作接口
macro | arguments |
---|---|
HASH_ADD_INT |
(head, keyfield_name, item_ptr) |
HASH_REPLACE_INT |
(head, keyfield_name, item_ptr, replaced_item_ptr) |
HASH_FIND_INT |
(head, key_ptr, item_ptr) |
HASH_ADD_STR |
(head, keyfield_name, item_ptr) |
HASH_REPLACE_STR |
(head, keyfield_name, item_ptr, replaced_item_ptr) |
HASH_FIND_STR |
(head, key_ptr, item_ptr) |
HASH_ADD_PTR |
(head, keyfield_name, item_ptr) |
HASH_REPLACE_PTR |
(head, keyfield_name, item_ptr, replaced_item_ptr) |
HASH_FIND_PTR |
(head, key_ptr, item_ptr) |
HASH_DEL |
(head, item_ptr) |
HASH_SORT |
(head, cmp) |
HASH_COUNT |
(head) |
举例
#include <stdio.h> /* gets */
#include <stdlib.h> /* atoi, malloc */
#include <string.h> /* strcpy */
#include "uthash.h"
struct my_struct {
int id; /* key */
char name[10];
UT_hash_handle hh; /* makes this structure hashable */
};
struct my_struct *users = NULL;
void add_user(int user_id, char *name) {
struct my_struct *s;
HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */
if (s == NULL) {
s = (struct my_struct *)malloc(sizeof *s);
s->id = user_id;
HASH_ADD_INT(users, id, s); /* id: name of key field */
}
strcpy(s->name, name);
}
struct my_struct *find_user(int user_id) {
struct my_struct *s;
HASH_FIND_INT(users, &user_id, s); /* s: output pointer */
return s;
}
void delete_user(struct my_struct *user) {
HASH_DEL(users, user); /* user: pointer to deletee */
free(user);
}
list操作
utlist提供了链表的操作,支持三种链表:单链表、双链表、循环双链表。
官方文档详细介绍了utlist的使用。在源码中包含utlist.h头文件即可。
https://troydhanson.github.io/uthash/utlist.html
定义list结构体
在你定义的list中嵌入next、prev指针,就可实现单链表或者双链表。
typedef struct element {
char *name;
struct element *prev; /* needed for a doubly-linked list only */
struct element *next; /* needed for singly- or doubly-linked lists */
} element;
list操作接口
支持list的头插法和尾插法的插入接口、查询接口、删除接口、遍历、排序等。
Prepend意味着在现有的列表头(如果有的话)前面插入一个元素,将列表头更改为新元素。Append意味着在列表的末尾添加一个元素,因此它成为新的尾元素。Concatenate接受两个正确构造的列表,并将第二个列表附加到第一个列表。要在任意元素(而不是列表头)之前添加前缀,请使用prepend ELEM宏族。要在任意元素元素之后添加元素而不是列表头,请使用append ELEM宏族。
Singly-linked | Doubly-linked | Circular, doubly-linked |
---|---|---|
LL_PREPEND(head,add); |
DL_PREPEND(head,add); |
CDL_PREPEND(head,add); |
LL_PREPEND_ELEM(head,ref,add); |
DL_PREPEND_ELEM(head,ref,add); |
CDL_PREPEND_ELEM(head,ref,add); |
LL_APPEND_ELEM(head,ref,add); |
DL_APPEND_ELEM(head,ref,add); |
CDL_APPEND_ELEM(head,ref,add); |
LL_REPLACE_ELEM(head,del,add); |
DL_REPLACE_ELEM(head,del,add); |
CDL_REPLACE_ELEM(head,del,add); |
LL_APPEND(head,add); |
DL_APPEND(head,add); |
CDL_APPEND(head,add); |
LL_INSERT_INORDER(head,add,cmp); |
DL_INSERT_INORDER(head,add,cmp); |
CDL_INSERT_INORDER(head,add,cmp); |
LL_CONCAT(head1,head2); |
DL_CONCAT(head1,head2); |
`` |
LL_DELETE(head,del); |
DL_DELETE(head,del); |
CDL_DELETE(head,del); |
LL_SORT(head,cmp); |
DL_SORT(head,cmp); |
CDL_SORT(head,cmp); |
LL_FOREACH(head,elt) {…} |
DL_FOREACH(head,elt) {…} |
CDL_FOREACH(head,elt) {…} |
LL_FOREACH_SAFE(head,elt,tmp) {…} |
DL_FOREACH_SAFE(head,elt,tmp) {…} |
CDL_FOREACH_SAFE(head,elt,tmp1,tmp2) {…} |
LL_SEARCH_SCALAR(head,elt,mbr,val); |
DL_SEARCH_SCALAR(head,elt,mbr,val); |
CDL_SEARCH_SCALAR(head,elt,mbr,val); |
LL_SEARCH(head,elt,like,cmp); |
DL_SEARCH(head,elt,like,cmp); |
CDL_SEARCH(head,elt,like,cmp); |
LL_LOWER_BOUND(head,elt,like,cmp); |
DL_LOWER_BOUND(head,elt,like,cmp); |
CDL_LOWER_BOUND(head,elt,like,cmp); |
LL_COUNT(head,elt,count); |
DL_COUNT(head,elt,count); |
CDL_COUNT(head,elt,count); |
array操作
utarray实现了动态数组的功能。可存储整型数组和字符串,也可自定义其他类型。
https://troydhanson.github.io/uthash/utarray.html
utarray操作接口
macro | description |
---|---|
utarray_new(UT_array *a, UT_icd *icd) |
allocate a new array |
utarray_free(UT_array *a) |
free an allocated array |
utarray_push_back(UT_array *a,void *p) |
push element p onto a |
utarray_pop_back(UT_array *a) |
pop last element from a |
utarray_len(UT_array *a) |
get length of a |
utarray_insert(UT_array *a,void *p, int j) |
insert element p to index j |
utarray_inserta(UT_array *a,UT_array *w, int j) |
insert array w into array a at index j |
utarray_concat(UT_array *dst,UT_array *src) |
copy src to end of dst array |
utarray_clear(UT_array *a) |
clear all elements from a, setting its length to zero |
utarray_sort(UT_array *a,cmpfcn *cmp) |
sort elements of a using comparison function |
utarray_find(UT_array *a,void *v, cmpfcn *cmp) |
find element v in utarray (must be sorted) |
utarray_front(UT_array *a) |
get first element of a |
utarray_next(UT_array *a,void *e) |
get element of a following e (front if e is NULL) |
utarray_prev(UT_array *a,void *e) |
get element of a before e (back if e is NULL) |
utarray_back(UT_array *a) |
get last element of a |
举例
#include <stdio.h>
#include "utarray.h"
int main() {
UT_array *nums;
int i, *p;
utarray_new(nums,&ut_int_icd);
for(i=0; i < 10; i++) utarray_push_back(nums,&i);
for(p=(int*)utarray_front(nums);
p!=NULL;
p=(int*)utarray_next(nums,p)) {
printf("%d\n",*p);
}
utarray_free(nums);
return 0;
}
string操作
utstring实现了动态字符串的功能。https://github.com/troydhanson/uthash
utstring操作接口
utstring_new(s) |
allocate a new utstring |
---|---|
utstring_renew(s) |
allocate a new utstring (if s is NULL ) otherwise clears it |
utstring_free(s) |
free an allocated utstring |
utstring_init(s) |
init a utstring (non-alloc) |
utstring_done(s) |
dispose of a utstring (non-alloc) |
utstring_printf(s,fmt,…) |
printf into a utstring (appends) |
utstring_bincpy(s,bin,len) |
insert binary data of length len (appends) |
utstring_concat(dst,src) |
concatenate src utstring to end of dst utstring |
utstring_clear(s) |
clear the content of s (setting its length to 0) |
utstring_len(s) |
obtain the length of s as an unsigned integer |
utstring_body(s) |
get char* to body of s (buffer is always null-terminated) |
utstring_find(s,pos,str,len) |
forward search from pos for a substring |
utstring_findR(s,pos,str,len) |
reverse search from pos for a substring |
举例
#include <stdio.h>
#include "utstring.h"
int main() {
UT_string *s;
utstring_new(s);
utstring_printf(s, "hello world!" );
printf("%s\n", utstring_body(s));
utstring_free(s);
return 0;
}
原文地址:https://www.cnblogs.com/lvzh/p/15111775.html
- Python爬虫之豆瓣音乐及糗事百科
- oracle、mysql 分页查询比较
- Linux乱码问题解决方案
- JDBC为什么要使用PreparedStatement而不是Statement
- tcpdump捕捉样例
- Log4j详细使用教程
- Android系统线控和歌曲信息屏显的那点事
- 利用Spring中同名Bean相互覆盖的特性,定制平台的类内容。
- 关于java传参
- 浅析ButterKnife
- SQL Server常用语句
- pyecharts(一):Python可视化利器
- 如何在Python中保存ARIMA时间序列预测模型
- SVN+Apache域用户认证配置方法_Windows(转,重新排版,部分内容更新优化)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android Studio 4.0新特性及升级异常问题的解决方案
- Android Studio 4.0 正式发布在Ubuntu 20.04中安装的方法
- Android Studio 4.0 新功能中的Live Layout Inspector详解
- Android实现滑动刻度尺效果
- Android 仿微信发动态九宫格拖拽、删除功能
- android自定义等级评分圆形进度条
- Android Fragment实现底部通知栏
- Flutter实现局部刷新
- Android自定义条形对比统计图
- Android底部菜单栏(RadioGroup+Fragment)美化
- android自定义环形统计图动画
- 在Android环境下WebView中拦截所有请求并替换URL示例详解
- Android自定义控件横向柱状统计图
- Android处理视图圆角和色彩的工具类
- Flutter之Timer实现短信验证码获取60s倒计时功能的代码