glib的GHashTable实践

前言

        hash就是键值对。相比数组更加灵活。

函数指针

哈希函数指针,赋值NULL即可

guint
(*GHashFunc) (gconstpointer key);

比较函数指针

gboolean
(*GEqualFunc) (gconstpointer a,
               gconstpointer b);

Specifies the type of a function used to test two values for equality. The function should return TRUE if both values are equal and FALSE otherwise.

        指定用于测试两个值是否相等的函数的类型。如果两个值相等,函数应该返回TRUE,否则返回FALSE。

资源释放函数指针

void
(*GDestroyNotify) (gpointer data);

Specifies the type of function which is called when a data element is destroyed. It is passed the pointer to the data element and should free any memory and resources allocated for it.

        指定在销毁数据元素时调用的函数类型。将指向数据元素的指针传递给它,并释放为它分配的所有内存和资源。

一 例程1相关函数

g_hash_table_new :创建一个hash表

GHashTable *
g_hash_table_new (GHashFunc hash_func,
                  GEqualFunc key_equal_func);

第一个参数传值NULL,第二个参数可以传值NULL,也可以自己写一个,例如下面这个

gboolean
key_equal_func (gconstpointer a,
               gconstpointer b)
{
	if(strcmp(a,b) == 0){
		return TRUE;
	}
	return FALSE;
}

Creates a new GHashTable with a reference count of 1.

Hash values returned by hash_func are used to determine where keys are stored within the GHashTable data structure. The g_direct_hash(), g_int_hash(), g_int64_hash(), g_double_hash() and g_str_hash() functions are provided for some common types of keys. If hash_func is NULL, g_direct_hash() is used.

key_equal_func is used when looking up keys in the GHashTable. The g_direct_equal(), g_int_equal(), g_int64_equal(), g_double_equal() and g_str_equal() functions are provided for the most common types of keys. If key_equal_func is NULL, keys are compared directly in a similar fashion to g_direct_equal(), but without the overhead of a function call.

Parameters

hash_func
a function to create a hash value from a key
 
key_equal_func
a function to check two keys for equality
 
Returns

a new GHashTable

g_hash_table_insert:插入键值对,插入失败返回FALSE

gboolean
g_hash_table_insert (GHashTable *hash_table,
                     gpointer key,
                     gpointer value);

Inserts a new key and value into a GHashTable.

If the key already exists in the GHashTable its current value is replaced with the new value. If you supplied a value_destroy_func when creating the GHashTable, the old value is freed using that function. If you supplied a key_destroy_func when creating the GHashTable, the passed key is freed using that function.

Parameters

hash_table
a GHashTable
 
key
a key to insert
 
value
the value to associate with the key
 
Returns

TRUE if the key did not exist yet

g_hash_table_new_full:创建一个hash表

GHashTable *
g_hash_table_new_full (GHashFunc hash_func,
                       GEqualFunc key_equal_func,
                       GDestroyNotify key_destroy_func,
                       GDestroyNotify value_destroy_func);

第三个参数用于回收key资源,第四个参数用于回收value资源

g_hash_table_remove_all:释放hash表

void
g_hash_table_remove_all (GHashTable *hash_table);

如果g_hash_table_new_full创建表,并且给了第三个删除和第四和删除,调用g_hash_table_remove_all后,这两个指针函数将会被依次调用。例如

void  key_destroy_func(gpointer data)
{
	printf("free %s\n",data);
	free(data);
}
void  value_destroy_func(gpointer data)
{
	printf("free %s\n",data);
	free(data);
}

g_hash_table_lookup ():查找key对应的value

gpointer
g_hash_table_lookup (GHashTable *hash_table,
                     gconstpointer key);

Looks up a key in a GHashTable. Note that this function cannot distinguish between a key that is not present and one which is present and has the value NULL. If you need this distinction, use g_hash_table_lookup_extended().

Parameters

hash_table
a GHashTable
 
key
the key to look up
 
Returns

the associated value, or NULL if the key is not found.

g_hash_table_replace:替换value值

这个函数的返回值需要注意一下,如果KEY值不存在,返回TRUE,如果KEY值存在返回FALSE,返回FALSE时,不代表replace失败。

gboolean
g_hash_table_insert (GHashTable *hash_table,
                     gpointer key,
                     gpointer value);

Inserts a new key and value into a GHashTable.

If the key already exists in the GHashTable its current value is replaced with the new value. If you supplied a value_destroy_func when creating the GHashTable, the old value is freed using that function. If you supplied a key_destroy_func when creating the GHashTable, the passed key is freed using that function.

Parameters

hash_table
a GHashTable
 
key
a key to insert
 
value
the value to associate with the key
 
Returns

TRUE if the key did not exist yet

g_hash_table_get_keys:输出key是列表

GList *
g_hash_table_get_keys (GHashTable *hash_table);

Retrieves every key inside hash_table . The returned data is valid until changes to the hash release those keys.

This iterates over every entry in the hash table to build its return value. To iterate over the entries in a GHashTable more efficiently, use a GHashTableIter.

Parameters

hash_table
a GHashTable
 
Returns

a GList containing all the keys inside the hash table. The content of the list is owned by the hash table and should not be modified or freed. Use g_list_free() when done using the list.

链表结构体struct GList

struct GList {
  gpointer data;
  GList *next;
  GList *prev;
};

 遍历一个链表

GList *list;
for (list = list; list != NULL; list = list->next)
  {
    // do something with list->data
  }

二 测试例程1

本次例程使用整数作为KEY,使用整数作为VALUE

源码:main.c

#include <glib.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

void init_table(GHashTable *ht)
{
	int i = 0;
	int ret = 0;
	for(int i = 0;i < 5;i++){
		ret = g_hash_table_insert (ht,(gpointer)i,(gpointer)((i+1)*5));
		if(!ret){
			printf("insert error");
			exit(1);
		}
	}
	printf("init ok\n");
}

void show_keys(GHashTable *ht){
	GList* list = g_hash_table_get_keys (ht);
	int i = 0;
	for (list = list; list != NULL; list = list->next)
	{
		printf("key%d = %d\n",i,(int)list->data);
		i++;
	}
	printf("show_keys finish\n\n");
}

void show_table(GHashTable *ht)
{
	int i = 0;
	int value;
	for(int i = 0;i < 5;i++){
		value = (int)g_hash_table_lookup (ht,(gpointer)i);
		printf("key = %d,value = %d\n",i,value);
	}
	printf("show_table finish\n\n");
}

int main(int argc,char *argv[])
{	
	GHashTable *ht = g_hash_table_new(NULL,NULL);
	init_table(ht);
	show_table(ht);
	show_keys(ht);
	return 0;
}

Makefile

LINK_INCLUDE += -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
LINK_INCLUDE += -I/usr/include/glib-2.0/
 
 
app1:main.c
	gcc main.c -lglib-2.0 $(LINK_INCLUDE) -o app1
app2:main.c
	gcc main.c `pkg-config --cflags --libs glib-2.0` -o app2
install_help:
	sudo apt-get install libglib2.0-doc
	sudo apt-get install devhelp
.PHONY:doc
doc:
	$(shell devhelp)
.PHONY:clean
clean:
	rm -f *.o app1 app2

运行结果:

lkmao@ubuntu:/big/glib/x86/g_hash$ ./app1
init ok
key = 0,value = 5
key = 1,value = 10
key = 2,value = 15
key = 3,value = 20
key = 4,value = 25
show_table finish

key0 = 4
key1 = 2
key2 = 3
key3 = 1
key4 = 0
show_keys finish

lkmao@ubuntu:/big/glib/x86/g_hash$


三 测试例程2

相比例程1,次例程使用字符串作为KEY,使用字符串作为value

源码:main.c

#include <glib.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void init_table(GHashTable *ht)
{
	int i = 0;
	int ret = 0;
	char *key;
	char *value;
	
	for(int i = 0;i < 5;i++){
		key = malloc(10);
		sprintf(key,"hello%d",i);
		
		value = malloc(10);
		sprintf(value,"world%d",i);
		ret = g_hash_table_insert (ht,(gpointer)key,(gpointer)value);
		if(!ret){
			printf("insert error");
			exit(1);
		}
	}
	printf("init ok\n");
}

void show_keys(GHashTable *ht){
	GList* plist = g_hash_table_get_keys (ht);
	GList* list;
	int i = 0;
	for (list = plist; list != NULL; list = list->next)
	{
		printf("key%d = %s\n",i,(char*)list->data);
		i++;
	}
	printf("count = %d\n",i);
	printf("show_keys finish\n\n");
}

void show_table(GHashTable *ht)
{	
	GList* plist = g_hash_table_get_keys (ht);
	GList* list;
	int i = 0;
	gpointer value;
	for (list = plist; list != NULL; list = list->next)
	{
		value = g_hash_table_lookup (ht,(gpointer)list->data);
		printf("key = %s,value = %s\n",(char*)list->data,(char*)value);
		i++;
	}
	printf("count = %d\n",i);
}

void release_table(GHashTable *ht)
{
	GList* plist = g_hash_table_get_keys (ht);
	GList* list;
	gpointer *value;
	
	for (list = plist; list != NULL; list = list->next)
	{
		value = g_hash_table_lookup (ht,(gpointer)list->data);
		g_hash_table_remove(ht,list->data);
		free(value);
		free(list->data);
	}
	printf("release_table finish\n\n");
}

void  key_destroy_func(gpointer data)
{
	printf("free %s\n",(char*)data);
	free(data);
}
void  value_destroy_func(gpointer data)
{
	printf("free %s\n",(char*)data);
	free(data);
}

gboolean
key_equal_func (gconstpointer a,
               gconstpointer b)
{
	if(strcmp(a,b) == 0){
		return TRUE;
	}
	return FALSE;
}

int main(int argc,char *argv[])
{	
	GHashTable *ht = g_hash_table_new_full(NULL,key_equal_func,
				key_destroy_func,value_destroy_func);
	
	init_table(ht);
	show_table(ht);
	show_keys(ht);
	char *new_value = malloc(5);
	sprintf(new_value,"new_str");
	show_table(ht);
	g_hash_table_remove_all(ht);
	return 0;
}

运行结果:

lkmao@ubuntu:/big/glib/x86/g_hash$ ./app1
init ok
key = hello3,value = world3
key = hello2,value = world2
key = hello1,value = world1
key = hello4,value = world4
key = hello0,value = world0
count = 5
key0 = hello3
key1 = hello2
key2 = hello1
key3 = hello4
key4 = hello0
count = 5
show_keys finish

key = hello3,value = world3
key = hello2,value = world2
key = hello1,value = world1
key = hello4,value = world4
key = hello0,value = world0
count = 5
free hello0
free world0
free hello4
free world4
free hello1
free world1
free hello2
free world2
free hello3
free world3
lkmao@ubuntu:/big/glib/x86/g_hash$

结束

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千册

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值