博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
glib 散列表
阅读量:6721 次
发布时间:2019-06-25

本文共 7901 字,大约阅读时间需要 26 分钟。

原文地址:

编译:gcc -g -Wall -O0 fuck.c -o fuck `pkg-config --libs --cflags glib-2.0`

1

 一些简单的散列表操作     有错误需要调试

这里是一些示例,可以生动地展示以上的理论:

 
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(hash,
"
Virginia
"
,
"
Richmond
"
);
g_hash_table_insert(hash,
"
Texas
"
,
"
Austin
"
);
g_hash_table_insert(hash,
"
Ohio
"
,
"
Columbus
"
);
printf(
"
There are %d keys in the hash\n
"
, g_hash_table_size(hash));
printf(
"
The capital of Texas is %s\n
"
, g_hash_table_lookup(hash,
"
Texas
"
));
gboolean found
=
g_hash_table_remove(hash,
"
Virginia
"
);
printf(
"
The value 'Virginia' was %sfound and removed\n
"
, found
?
""
:
"
not
"
);
g_hash_table_destroy(hash);
return
0
;
}
***** Output *****
There are 3 keys in the hash
The capital of Texas is Austin
The value 'Virginia' was found and removed

2

插入和替换值

当使用 g_hash_table_insert 插入键时,GHashTable 首先检查那个键是否已经存在。如果已经存在,那么那个值会被替换,

而键不会被替换。如果希望同时替换键和值,那么需要使用 g_hash_table_replace。它稍有不同,因此在下面同时展示了二者:

 
#include
<
glib.h
>
#include
<
stdio.h
>
static
char
*
texas_1,
*
texas_2;
void
key_destroyed(gpointer data) {
printf(
"
Got a key destroy call for %s\n
"
, data
==
texas_1
?
"
texas_1
"
:
"
texas_2
"
);
}
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new_full(g_str_hash, g_str_equal,
(GDestroyNotify)key_destroyed, NULL);
texas_1
=
g_strdup(
"
Texas
"
);
texas_2
=
g_strdup(
"
Texas
"
);
g_hash_table_insert(hash, texas_1,
"
Austin
"
);
printf(
"
Calling insert with the texas_2 key\n
"
);
g_hash_table_insert(hash, texas_2,
"
Houston
"
);
printf(
"
Calling replace with the texas_2 key\n
"
);
g_hash_table_replace(hash, texas_2,
"
Houston
"
);
printf(
"
Destroying hash, so goodbye texas_2\n
"
);
g_hash_table_destroy(hash);
g_free(texas_1);
g_free(texas_2);
return
0
;
}
***** Output *****
Calling insert with the texas_2 key
Got a key destroy call for texas_2
Calling replace with the texas_2 key
Got a key destroy call for texas_1
Destroying hash, so goodbye texas_2
Got a key destroy call for texas_2

3

遍历 键/值 对

有时需要遍历所有的 键/值 对。这里是如何使用 g_hash_table_foreach 来完成那项任务:

 
#include
<
glib.h
>
#include
<
stdio.h
>
void
iterator(gpointer key, gpointer value, gpointer user_data) {
printf(user_data,
*
(gint
*
)key, value);
}
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new(g_int_hash, g_int_equal);
gint
*
k_one
=
g_new(gint,
1
),
*
k_two
=
g_new(gint,
1
),
*
k_three
=
g_new(gint,
1
);
*
k_one
=
1
,
*
k_two
=
2
,
*
k_three
=
3
;
g_hash_table_insert(hash, k_one,
"
one
"
);
g_hash_table_insert(hash, k_two,
"
four
"
);
g_hash_table_insert(hash, k_three,
"
nine
"
);
g_hash_table_foreach(hash, (GHFunc)iterator,
"
The square of %d is %s\n
"
);
g_hash_table_destroy(hash);
return
0
;
}
***** Output *****
The square of 1 is one
The square of 2 is four
The square of 3 is nine
4

查找条目

使用 g_hash_table_find 函数来查找某个特定的值。这个函数支持查看每一个 键/值 对,直到定位到期望的值。这里是一个示例:

 
#include
<
glib.h
>
#include
<
stdio.h
>
void
value_destroyed(gpointer data) {
printf(
"
Got a value destroy call for %d\n
"
, GPOINTER_TO_INT(data));
}
gboolean finder(gpointer key, gpointer value, gpointer user_data) {
return
(GPOINTER_TO_INT(key)
+
GPOINTER_TO_INT(value))
==
42
;
}
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL,
(GDestroyNotify)value_destroyed);
g_hash_table_insert(hash, GINT_TO_POINTER(
6
), GINT_TO_POINTER(
36
));
g_hash_table_insert(hash, GINT_TO_POINTER(
10
), GINT_TO_POINTER(
12
));
g_hash_table_insert(hash, GINT_TO_POINTER(
20
), GINT_TO_POINTER(
22
));
gpointer item_ptr
=
g_hash_table_find(hash, (GHRFunc)finder, NULL);
gint item
=
GPOINTER_TO_INT(item_ptr);
printf(
"
%d + %d == 42\n
"
, item,
42
-
item);
g_hash_table_destroy(hash);
return
0
;
}
***** Output *****
36 + 6 == 42
Got a value destroy call for 36
Got a value destroy call for 22
Got a value destroy call for 12

5

难处理的情形:从表中删除

偶尔可能需要从一个 GHashTable 中删除某个条目,但却没有获得 GHashTable 所提供的任意 GDestroyNotify 函数的回调。

要完成此任务,或者可以根据具体的键使用 g_hash_table_steal,或者根据所有匹配某个条件的键使用 g_hash_table_foreach_steal。

 
#include
<
glib.h
>
#include
<
stdio.h
>
gboolean wide_open(gpointer key, gpointer value, gpointer user_data) {
return
TRUE;
}
void
key_destroyed(gpointer data) {
printf(
"
Got a GDestroyNotify callback\n
"
);
}
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new_full(g_str_hash, g_str_equal,
(GDestroyNotify)key_destroyed,
(GDestroyNotify)key_destroyed);
g_hash_table_insert(hash,
"
Texas
"
,
"
Austin
"
);
g_hash_table_insert(hash,
"
Virginia
"
,
"
Richmond
"
);
g_hash_table_insert(hash,
"
Ohio
"
,
"
Columbus
"
);
g_hash_table_insert(hash,
"
Oregon
"
,
"
Salem
"
);
g_hash_table_insert(hash,
"
New York
"
,
"
Albany
"
);
printf(
"
Removing New York, you should see two callbacks\n
"
);
g_hash_table_remove(hash,
"
New York
"
);
if
(g_hash_table_steal(hash,
"
Texas
"
)) {
printf(
"
Texas has been stolen, %d items remaining\n
"
, g_hash_table_size(hash));
}
printf(
"
Stealing remaining items\n
"
);
g_hash_table_foreach_steal(hash, (GHRFunc)wide_open, NULL);
printf(
"
Destroying the GHashTable, but it's empty, so no callbacks\n
"
);
g_hash_table_destroy(hash);
return
0
;
}
***** Output *****
Removing New York, you should see two callbacks
Got a GDestroyNotify callback
Got a GDestroyNotify callback
Texas has been stolen, 3 items remaining
Stealing remaining items
Destroying the GHashTable, but it's empty, so no callbacks

6

高级查找:找到键和值

针对需要从表中同时获得键和值的情况,GHashTable 提供了一个 g_hash_table_lookup_extended 函数。

它与 g_hash_table_lookup 非常类似,但要接受更多两个参数。这些都是“out”参数;也就是说,它们是双重间接指针,当数据被定位时将指向它

。这里是它的工作方式:

 
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(hash,
"
Texas
"
,
"
Austin
"
);
g_hash_table_insert(hash,
"
Virginia
"
,
"
Richmond
"
);
g_hash_table_insert(hash,
"
Ohio
"
,
"
Columbus
"
);
char
*
state
=
NULL;
char
*
capital
=
NULL;
char
**
key_ptr
=
&
state;
char
**
value_ptr
=
&
capital;
gboolean result
=
g_hash_table_lookup_extended(hash,
"
Ohio
"
, (gpointer
*
)key_ptr, (gpointer
*
)value_ptr);
if
(result) {
printf(
"
Found that the capital of %s is %s\n
"
, capital, state);
}
if
(
!
g_hash_table_lookup_extended(hash,
"
Vermont
"
, (gpointer
*
)key_ptr, (gpointer
*
)value_ptr)) {
printf(
"
Couldn't find Vermont in the hash table\n
"
);
}
g_hash_table_destroy(hash);
return
0
;
}
***** Output *****
Found that the capital of Columbus is Ohio
Couldn't find Vermont in the hash table

7

每个键多个值   有错误需要调试

到目前为止已经介绍了每个键只拥有一个值的散列。不过有时您需要让一个键持有多个值。当出现这种需求时,

使用 GSList 作为值并及 GSList 添加新的值通常是一个好的解决方案。不过,这需要稍多一些工作,如本例中所示:

 
#include
<
glib.h
>
#include
<
stdio.h
>
void
print(gpointer key, gpointer value, gpointer data) {
printf(
"
Here are some cities in %s:
"
, key);
g_slist_foreach((GSList
*
)value, (GFunc)printf, NULL);
printf(
"
\n
"
);
}
void
destroy(gpointer key, gpointer value, gpointer data) {
printf(
"
Freeing a GSList, first item is %s\n
"
, ((GSList
*
)value)
->
data);
g_slist_free(value);
}
int
main(
int
argc,
char
**
argv) {
GHashTable
*
hash
=
g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(hash,
"
Texas
"
,
g_slist_append(g_hash_table_lookup(hash,
"
Texas
"
),
"
Austin
"
));
g_hash_table_insert(hash,
"
Texas
"
,
g_slist_append(g_hash_table_lookup(hash,
"
Texas
"
),
"
Houston
"
));
g_hash_table_insert(hash,
"
Virginia
"
,
g_slist_append(g_hash_table_lookup(hash,
"
Virginia
"
),
"
Richmond
"
));
g_hash_table_insert(hash,
"
Virginia
"
,
g_slist_append(g_hash_table_lookup(hash,
"
Virginia
"
),
"
Keysville
"
));
g_hash_table_foreach(hash, print, NULL);
g_hash_table_foreach(hash, destroy, NULL);
g_hash_table_destroy(hash);
return
0
;
}
***** Output *****
Here are some cities in Texas: Austin Houston
Here are some cities in Virginia: Richmond Keysville
Freeing a GSList, first item is Austin
Freeing a GSList, first item is Richmond

转载地址:http://bwjmo.baihongyu.com/

你可能感兴趣的文章
[shell]通过date获取上月变量
查看>>
java 消息机制 ActiveMQ入门实例
查看>>
关于HBA
查看>>
初学oracle物理存储结构遇到的一些问题
查看>>
C的文件操作——常用库函数
查看>>
mysql优化经验
查看>>
获取数据指纹和base64编码的编码方式
查看>>
使用go的net/http实现读取web页面
查看>>
Ant打包项目
查看>>
A disk issue on Linux server
查看>>
我的友情链接
查看>>
男子陷连环计借万元送人
查看>>
MySQL效能监控工具mysqlreport安装部署及相关收集内容的解释说明
查看>>
HTTP 1.1状态代码及其含义
查看>>
PHP响应JSON数据
查看>>
简单操作xshell
查看>>
存储崩溃强制上线是否完全不可行?
查看>>
初识Vue.js
查看>>
x86-64汇编学习小节
查看>>
ovftool自动部署/导出ova/ovf模板
查看>>