C语言学习笔记01--C开源库uthash的使用

1、uthash概述

2、uthash使用

  • Linux下的安装

将下载下来的怎个目录拷贝到/usr/local/include下面

  • 初始化

uthash需要用户定义自己的数据结构,一个包含UT_hash_handle hh的结构体

还需要定义键和值(可选),这里将id作为key, name作为value

struct my_struct {
    int id;                    /* key */
    char name[10];
    UT_hash_handle hh;         /* makes this structure hashable */
};
typedef struct my_struct HashNode;
typedef struct my_struct *HashHead;
  • 添加 

key是int,可以使用 HASH_ADD_INT

key是字符串,可以使用 HASH_ADD_STR

key是指针,可以使用 HASH_ADD_PTR 

其它,可以使用 HASH_ADD,上述实际都是调用这个方法,不过简化了参数

void hashTabel_add(HashHead *head, HashNode *users) {
    // id是key的属性名字,虽然很奇怪,实际作为宏参数会被替换掉
	// 可以看下面源码,intfield会替换换成&((add)->fieldname)
	if(!find_user(*head, users->id))
    	HASH_ADD_INT(*head, id, users);
}

#define HASH_ADD_INT(head,intfield,add)                                          \
    HASH_ADD(hh,head,intfield,sizeof(int),add)
#define HASH_ADD(hh,head,fieldname,keylen_in,add)                                \
  HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add)
  • 替换 

与添加差不多,会在添加前,删除key相同的节点,再添加新的节点

如果key是int,可以使用 HASH_REPLACE_INT

void replace_user(HashHead *head, HashNode *newNode) {
    HashNode *oldNode = find_user(*head, newNode->id);
    if (oldNode)
        HASH_REPLACE_INT(*head, id, newNode, oldNode);
}
  •  查找

根据key查找节点

如果key是int,可以使用 HASH_FIND_INT

HashNode *find_user(HashHead head, int user_id) {
	HashNode *s;
	HASH_FIND_INT(head, &user_id, s);  /* s: output pointer */
	return s;
}
  • 删除 
void delete_user(HashHead *head,HashNode *user) {
    if (user) {
        HASH_DEL(*head, user);  /* user: pointer to deletee */
        free(user);             /* optional; it's up to you! */
    }
}
  • 计数 
int count_user(HashHead head) {
    return HASH_COUNT(head);
}
  • 遍历
void print_user(HashHead head) {
    HashNode *s;
    printf("size is %d\n", count_user(head));
    for (s = head; s != NULL; s = s->hh.next) {
        printf("user id %d, name %s\n", s->id, s->name);
    }
}
void print_user_iterator(HashHead head) {
    HashNode *s, *tmp;
    printf("size is %d\n", count_user(head));
    HASH_ITER(hh, head, s, tmp) {
        printf("user id %d: name %s\n", s->id, s->name);
        /* ... it is safe to delete and free s here */
    }
}
  • 排序
int name_sort(HashNode *a, HashNode *b) {
    return strcmp(a->name,b->name);
}

int id_sort(HashNode *a, HashNode *b) {
    return (a->id - b->id);
}

void sort_by_name(HashHead *head) {
    HASH_SORT(*head, name_sort);
}

void sort_by_id(HashHead *head) {
    HASH_SORT(*head, id_sort);
}

3、完整代码

#include <stdio.h>
#include <stdlib.h>
#include "uthash.h"

typedef struct my_struct {
    int id;            /* we'll use this field as the key */
    char name[10];
    UT_hash_handle hh; /* makes this structure hashable */
}HashNode;
typedef HashNode* HashHead;

int count_user(HashHead head);
HashNode *find_user(HashHead head, int user_id) {
    HashNode *s;
    HASH_FIND_INT(head, &user_id, s);  /* s: output pointer */
    return s;
}
void add_user(HashHead *head, HashNode *users) {
    if(!find_user(*head, users->id))
        HASH_ADD_INT(*head, id, users);
}
void replace_user(HashHead *head, HashNode *newNode) {
    HashNode *oldNode = find_user(*head, newNode->id);
    if (oldNode)
        HASH_REPLACE_INT(*head, id, newNode, oldNode);
}
void delete_user(HashHead *head,HashNode *user) {
    if (user) {
        HASH_DEL(*head, user);  /* user: pointer to deletee */
        free(user);             /* optional; it's up to you! */
    }
}
void print_user(HashHead head) {
    HashNode *s;
    printf("size is %d\n", count_user(head));
    for (s = head; s != NULL; s = s->hh.next) {
        printf("user id %d, name %s\n", s->id, s->name);
    }
}
void print_user_iterator(HashHead head) {
    HashNode *s, *tmp;
    printf("size is %d\n", count_user(head));
    HASH_ITER(hh, head, s, tmp) {
        printf("user id %d: name %s\n", s->id, s->name);
        /* ... it is safe to delete and free s here */
    }
}
int count_user(HashHead head) {
    return HASH_COUNT(head);
}
int name_sort(HashNode *a, HashNode *b) {
	   return strcmp(a->name,b->name);
}

int id_sort(HashNode *a, HashNode *b) {
	   return (a->id - b->id);
}

void sort_by_name(HashHead *head) {
	   HASH_SORT(*head, name_sort);
}

void sort_by_id(HashHead *head) {
	   HASH_SORT(*head, id_sort);
}
int main()
{
    printf("--------------init---------------\n");
    HashHead head = NULL;
    printf("--------------add---------------\n");
    HashNode *node = malloc(sizeof(HashNode));
    node->id = 1;
    strcpy(node->name, "tom");
    add_user(&head, node);

    node = malloc(sizeof(HashNode));
    node->id = 2;
    strcpy(node->name, "jerry");
    add_user(&head, node);

    node = malloc(sizeof(HashNode));
    node->id = 3;
    strcpy(node->name, "jack");
    add_user(&head, node);

    node = malloc(sizeof(HashNode));
    node->id = 0;
    strcpy(node->name, "zero");
    add_user(&head, node);

    print_user(head);

    printf("--------------replace---------------\n");
    HashNode *newNode = malloc(sizeof(HashNode));
    newNode->id = 3;
    strcpy(newNode->name, "rose");
    replace_user(&head, newNode);
    print_user(head);

    printf("--------------delete---------------\n");
    delete_user(&head, find_user(head, 1));
    print_user(head);
    printf("--------------sort-by-id---------------\n");
    sort_by_id(&head);
    print_user(head);
    printf("--------------sort-by-name---------------\n");
    sort_by_name(&head);
    print_user(head);
    return 0;
}

4、参考文献

https://blog.csdn.net/qq_23091073/article/details/86485095

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值