当前位置: 首页 > news >正文

南阳网站开发公司做推文的编辑网站

南阳网站开发公司,做推文的编辑网站,wordpress头像本地,环保企业的网站怎么做目录 (1)uthash介绍和下载地址 (2)uthash基本用法 1.定义自己要使用的哈希表结构体 2.初始化哈希表的头指针 3.插入数据(不同key类型对应不同函数) 4.查找数据(不同key类型对应不同函数&a…

目录

(1)uthash介绍和下载地址

(2)uthash基本用法

1.定义自己要使用的哈希表结构体

2.初始化哈希表的头指针

3.插入数据(不同key类型对应不同函数)

4.查找数据(不同key类型对应不同函数)

5.获取键值对个数

6.排序

7.遍历

8.删除

(3)不同类型key值的uthash用法

1.字符串数组作为key

2.指针作为key

3.结构体作为key

(4)注意事项

插入元素时是重复key怎么办

删除数据时注意事项


(1)uthash介绍和下载地址

uthash是C的比较优秀的开源代码,它实现了常见的hash操作函数,例如查找、插入、删除等。该套开源代码采用宏的方式实现了hash函数的相关功能,支持c语言的任意数据结构作为key值(可以是基本类型,也可以是自定义的struct),甚至可以采用多个值作为key。

uthash使用所需文件:由于该代码采用宏的方式实现,所有的实现代码都在uthash.h文件中,因此只需要在自己的代码中包含该头文件即可。

uthash头文件下载地址:https://github.com/troydhanson/uthash

(2)uthash基本用法

1.定义自己要使用的哈希表结构体

如下所示,必须是结构体。

结构体可以有任意个成员,比如这里有4个成员。

变量名字也可以随便取。结构体名字也可以随便取,比如这里为Hash。

但是要包含UT_hash_handle hh这个成员,必须要有。不用对它赋值,就像下面这样就行。

后面我们会理解到,value就是这个结构体,key可以为这个结构体中的任意一种成员。

#include "uthash.h"#define NAME_LEN 10typedef struct {int id;int age;int grade;char name[NAME_LEN];UT_hash_handle hh;
} Hash;

2.初始化哈希表的头指针

初始化自己需要使用的哈希表,像下面这样(推荐用全局变量)

Hash *hashHead = NULL;

注意必须初始化为NULL,UTHash会根据指针是否为NULL进行判断是否需要初始化。

这里的hashHead指针叫做哈希表指针,类似于链表的头指针。

hashHead => key-value结构体 => key-value结构体 => key-value结构体

3.插入数据(不同key类型对应不同函数)

假设key类型为int,用HASH_ADD_INT

    Hash *data = (Hash *)malloc(sizeof(Hash));data->id = 1;data->age = 18;data->grade = 100;strcpy(data->name, "tom");HASH_ADD_INT(hashHead, id, data);

其中第一个参数为哈希表指针,第二个参数为哈希表结构体中的某个成员名,要将哪个成员作为key,就填哪个,第三个参数是value,为哈希表结构体指针。

4.查找数据(不同key类型对应不同函数)

假设key类型为int,用HASH_FIND_INT

    Hash *findRet = NULL;int key = 1;HASH_FIND_INT(hashHead, &key, findRet);if (findRet != NULL) {printf("%s\n", findRet->name);}

第一个参数为哈希表指针,第二个参数为待查找key的地址,第三个参数为传出参数,即查找到的value,找不到的话为NULL。

5.获取键值对个数

用HASH_COUNT

    int count = HASH_COUNT(hashHead);printf("%d\n", count);

6.排序

使用HASH_SORT,实现对哈希表中的元素排序。以下是先按照成绩降序,再年龄升序,再id升序排序的例子

int CmpFunc(Hash *a, Hash *b)
{/* 排序比较函数:返回值小于0表示不交换a和b,即升序 返回值小于0表示交换a和b,即降序*/if (a->grade != b->grade) {return b->grade - a->grade;}if (a->age != b->age) {return a->age - b->age;}return a->id - b->id;
}HASH_SORT(hashHead, CmpFunc);

7.遍历

使用HASH_ITER,实现对哈希表中元素的遍历

    Hash *curr = NULL;Hash *next = NULL;HASH_ITER(hh, hashHead, curr, next) {if (curr != NULL) {printf("curr grade=%d\n", curr->grade);}if (next != NULL) {printf("next grade=%d\n", next->grade);}}

curr和next这里是传出参数。

curr是遍历到的元素,next是curr的下一个元素。一般关注curr即可。

注意当curr为最后一个键值对时,next将会为NULL。

8.删除

使用HASH_DEL,实现对哈希表中元素的删除。

注意这里需要先找到哈希表中的目标元素,然后利用HASH_DEL进行删除,注意只是从哈希表中删除,然后再利用free进行内存回收。

    Hash *value = NULL;int boy_id = 1;HASH_FIND_INT(hashHead, &boy_id, value);if (value != NULL) {HASH_DEL(hashHead, value);free(value);}

如果要对哈希表中的全部元素删除,可遍历结合使用HASH_DEL

    Hash *curr = NULL;Hash *next = NULL;HASH_ITER(hh, hashHead, curr, next) {HASH_DEL(hashHead, curr);free(curr);}

(3)不同类型key值的uthash用法

不同类型key时,插入数据和查找数据的函数将会不同,其余基本还是相同的。

1.字符串数组作为key

比如哈希结构体Hash中成员chae name[10]

    // 设计一个数据Hash *data = (Hash *)malloc(sizeof(Hash));data->id = 1;data->age = 18;data->grade = 100;strcpy(data->name, "tom");// 以name作为key进行插入HASH_ADD_STR(hashHead, name, data);// 查找Hash *findRet = NULL;char boy_name[] = "tom";HASH_FIND_STR(hashHead, boy_name, findRet);if (findRet != NULL) {printf("%s\n", findRet->name);}

2.指针作为key

示例代码如下,注意查找时是传入指针的地址

#include <stdio.h>  
#include <string.h>#include "uthash.h"#define NAME_LEN 10typedef struct {void *key;int id;int age;int grade;char name[NAME_LEN];UT_hash_handle hh;
} Hash;Hash *hashHead = NULL;int main() 
{   // 某个值int *index = (int *)malloc(sizeof(int));*index = 99;// 设计一个数据Hash *data = (Hash *)malloc(sizeof(Hash));data->key = index;data->id = 1;data->age = 18;data->grade = 100;strcpy(data->name, "tom");// 以指针作为key进行插入HASH_ADD_PTR(hashHead, key, data);// 查找Hash *findRet = NULL;HASH_FIND_PTR(hashHead, &index, findRet); // 注意这里需要 &index if (findRet != NULL) {printf("%s\n", findRet->name);}return 0;  
}

3.结构体作为key

插入用HASH_ADD,与之前相比,多了两个参数,一个句柄hh,一个结构体大小

查找用HASH_FIND,与之前相比,多了两个参数,一个句柄hh,一个结构体大小

示例代码如下

#include <stdio.h>  
#include <string.h>#include "uthash.h"#define NAME_LEN 10typedef struct {int id;int age;int grade;} KeyStruct;typedef struct {KeyStruct key;char name[NAME_LEN];UT_hash_handle hh;
} Hash;Hash *hashHead = NULL;int main() 
{   // 设计一个数据Hash *data = (Hash *)malloc(sizeof(Hash));data->key.age = 18;data->key.grade = 100;data->key.id = 1;strcpy(data->name, "tom");// 以结构体作为key进行插入HASH_ADD(hh, hashHead, key, sizeof(KeyStruct), data);// 查找Hash *findRet = NULL;HASH_FIND(hh, hashHead, data, sizeof(KeyStruct), findRet);if (findRet != NULL) {printf("%s\n", findRet->name);}return 0;  
}

(4)注意事项

插入元素时是重复key怎么办

当使用 HASH_ADD_INT(或类似的 HASH_ADD 宏,但指定了整数类型作为键)向 uthash 哈希表中添加元素时,如果哈希表中已经存在一个具有相同键(key)的元素,那么新元素不会替换旧元素,而是会导致未定义行为(undefined behavior, UB)。

uthash 库没有提供直接的机制来更新已存在的键的值,它主要设计用于插入新元素和查找元素。如果你尝试使用相同的键插入一个新元素,而该键已经存在于哈希表中,uthash 不会自动合并或更新旧元素。相反,它可能会破坏哈希表的内部结构,导致数据损坏、内存泄漏或程序崩溃等问题。

如果你需要更新哈希表中已存在元素的值,你应该首先使用 HASH_FIND_INT(或相应的查找宏)来查找该元素。如果找到了,你可以直接修改该元素的值。如果没有找到,你可以使用 HASH_ADD_INT 来插入新元素。

下面是一个简单的示例,展示了如何安全地更新哈希表中已存在元素的值:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include "uthash.h"  typedef struct {  int id;      // 假设这是我们的键  int value;   // 我们要更新的值  UT_hash_handle hh;  
} HashElement;  HashElement *hashHead = NULL;  void update_or_add_element(int id, int newValue) {  HashElement *element;  HASH_FIND_INT(hashHead, &id, element);  if (element != NULL) {  // 如果元素已存在,则更新其值  element->value = newValue;  } else {  // 如果元素不存在,则创建并插入新元素  element = malloc(sizeof(HashElement));  if (element == NULL) {  fprintf(stderr, "Memory allocation failed\n");  exit(EXIT_FAILURE);  }  element->id = id;  element->value = newValue;  HASH_ADD_INT(hashHead, id, element);  }  
} void free_hash_table()
{HashElement *curr = NULL;HashElement *next = NULL;HASH_ITER(hh, hashHead, curr, next) {HASH_DEL(hashHead, curr);free(curr);}
}int main() 
{  // 插入一些初始元素  update_or_add_element(1, 100);  update_or_add_element(2, 200);  // 尝试更新已存在的元素 // 将id为1的元素的值更新为150  update_or_add_element(1, 150);  // 查找并打印更新后的值  HashElement *element;int target_key = 1;  HASH_FIND_INT(hashHead, &target_key, element);  if (element != NULL) {  printf("Value for id 1: %d\n", element->value); // 应该输出 150  }  // 释放哈希表中的所有元素free_hash_table(); return 0;  
}

删除数据时注意事项

如果你尝试传入一个不是哈希表中元素或键的地址来删除数据,那么结果将是未定义的。可能导致程序崩溃、数据损坏、或者无效果等。

为了避免这些问题,你应该始终确保:

  • 使用正确的键或指向哈希表中元素的指针来执行删除操作。
  • 如果你有指向哈希表中某个元素的指针,并且想要删除它,你应该直接使用该指针(确保它是指向包含 UT_hash_handle 成员的结构体的指针)和 HASH_DEL 宏。
  • 如果你只有键的值,你应该先使用查找宏(如 HASH_FIND_INT)来找到对应的元素,然后再使用 HASH_DEL 宏来删除它。

这里是一个简单的示例,展示了如何正确地删除哈希表中的元素:

#include <stdio.h>  
#include <stdlib.h>  
#include "uthash.h"  typedef struct {  int id;  char name[50];  UT_hash_handle hh;  
} HashElement;  HashElement *hashHead = NULL;  void delete_element(int id) {  HashElement *element;  HASH_FIND_INT(hashHead, &id, element);  if (element != NULL) {  HASH_DEL(hashHead, element);  free(element); // 不要忘记释放内存  }  
}  

end

http://www.yayakq.cn/news/58850/

相关文章:

  • 宁波做网站排名的公司有哪些怎么做网站镜像
  • 网站开发青岛php网站开发员工资
  • 旅游网站建设成都新华seo推广
  • 网站上传文件新品发布会流程
  • 好用心 做网站送女友县建设局 协会网站
  • 做公司集团网站响应式网页设计软件
  • 四川微信网站建设推拖拽式网站建设源码
  • 安徽中色十二冶金建设有限公司网站国家商标注册查询官网入口
  • 免费学校网站模板htmlwordpress 汉化失败
  • 昆明网站建设哪家强怎么建设vip电影网站
  • 安全联盟网站认证常州网络公司联系方式
  • 做网站,用什么做数据库最好济南专业网站优化
  • 郑州网站外包哪家好餐饮客户管理系统
  • 分类信息网站如何做排名微信商城怎么做
  • 周口师范做网站wordpress 主题显示
  • 哪些公司需要网站开发工程师购物网站建设过程视频
  • 做网站手机端不做PC可以吗网站的功能与建设方案
  • 网页模板哪个网站可以下载wordpress hello dolly
  • 免费推广网站都有哪些iis8搭建网站
  • 南宁网站建公司电话号码wdcp上传网站
  • 42区 网站开发指南出口网站建设方案
  • 网站建设 英文怎么说公司名称大全及最新
  • 重庆市工信部网站网站开发技术视频教程
  • 成都有哪些网站建设的公司logo设计在线生成免费图片加文字
  • 维护网站成本宣传册排版设计与制作
  • 微信做购物网站抽多少佣公司网站建设模块
  • 网站的seo优化怎么做阳江兼职招聘网
  • 义乌市评建设职称网站鄂州网站建设与设计
  • 龙岩网站定制成都大型商城网站建设
  • 怎样做网站关键词推广平台有哪几个