前言
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
Returnsa 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
ReturnsTRUE 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
Returnsthe 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
ReturnsTRUE 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
Returnsa 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$