• glib的GHashTable实践


    前言

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

    函数指针

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

    1. guint
    2. (*GHashFunc) (gconstpointer key);

    比较函数指针

    1. gboolean
    2. (*GEqualFunc) (gconstpointer a,
    3. 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。

    资源释放函数指针

    1. void
    2. (*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表

    1. GHashTable *
    2. g_hash_table_new (GHashFunc hash_func,
    3. GEqualFunc key_equal_func);

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

    1. gboolean
    2. key_equal_func (gconstpointer a,
    3. gconstpointer b)
    4. {
    5. if(strcmp(a,b) == 0){
    6. return TRUE;
    7. }
    8. return FALSE;
    9. }

    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

    1. gboolean
    2. g_hash_table_insert (GHashTable *hash_table,
    3. gpointer key,
    4. 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表

    1. GHashTable *
    2. g_hash_table_new_full (GHashFunc hash_func,
    3. GEqualFunc key_equal_func,
    4. GDestroyNotify key_destroy_func,
    5. GDestroyNotify value_destroy_func);

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

    g_hash_table_remove_all:释放hash表

    1. void
    2. g_hash_table_remove_all (GHashTable *hash_table);

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

    1. void key_destroy_func(gpointer data)
    2. {
    3. printf("free %s\n",data);
    4. free(data);
    5. }
    6. void value_destroy_func(gpointer data)
    7. {
    8. printf("free %s\n",data);
    9. free(data);
    10. }

    g_hash_table_lookup ():查找key对应的value

    1. gpointer
    2. g_hash_table_lookup (GHashTable *hash_table,
    3. 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失败。

    1. gboolean
    2. g_hash_table_insert (GHashTable *hash_table,
    3. gpointer key,
    4. 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是列表

    1. GList *
    2. 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

    1. struct GList {
    2. gpointer data;
    3. GList *next;
    4. GList *prev;
    5. };

     遍历一个链表

    1. GList *list;
    2. for (list = list; list != NULL; list = list->next)
    3. {
    4. // do something with list->data
    5. }

    二 测试例程1

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

    源码:main.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. void init_table(GHashTable *ht)
    6. {
    7. int i = 0;
    8. int ret = 0;
    9. for(int i = 0;i < 5;i++){
    10. ret = g_hash_table_insert (ht,(gpointer)i,(gpointer)((i+1)*5));
    11. if(!ret){
    12. printf("insert error");
    13. exit(1);
    14. }
    15. }
    16. printf("init ok\n");
    17. }
    18. void show_keys(GHashTable *ht){
    19. GList* list = g_hash_table_get_keys (ht);
    20. int i = 0;
    21. for (list = list; list != NULL; list = list->next)
    22. {
    23. printf("key%d = %d\n",i,(int)list->data);
    24. i++;
    25. }
    26. printf("show_keys finish\n\n");
    27. }
    28. void show_table(GHashTable *ht)
    29. {
    30. int i = 0;
    31. int value;
    32. for(int i = 0;i < 5;i++){
    33. value = (int)g_hash_table_lookup (ht,(gpointer)i);
    34. printf("key = %d,value = %d\n",i,value);
    35. }
    36. printf("show_table finish\n\n");
    37. }
    38. int main(int argc,char *argv[])
    39. {
    40. GHashTable *ht = g_hash_table_new(NULL,NULL);
    41. init_table(ht);
    42. show_table(ht);
    43. show_keys(ht);
    44. return 0;
    45. }

    Makefile

    1. LINK_INCLUDE += -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
    2. LINK_INCLUDE += -I/usr/include/glib-2.0/
    3. app1:main.c
    4. gcc main.c -lglib-2.0 $(LINK_INCLUDE) -o app1
    5. app2:main.c
    6. gcc main.c `pkg-config --cflags --libs glib-2.0` -o app2
    7. install_help:
    8. sudo apt-get install libglib2.0-doc
    9. sudo apt-get install devhelp
    10. .PHONY:doc
    11. doc:
    12. $(shell devhelp)
    13. .PHONY:clean
    14. clean:
    15. rm -f *.o app1 app2

    运行结果:

    1. lkmao@ubuntu:/big/glib/x86/g_hash$ ./app1
    2. init ok
    3. key = 0,value = 5
    4. key = 1,value = 10
    5. key = 2,value = 15
    6. key = 3,value = 20
    7. key = 4,value = 25
    8. show_table finish
    9. key0 = 4
    10. key1 = 2
    11. key2 = 3
    12. key3 = 1
    13. key4 = 0
    14. show_keys finish
    15. lkmao@ubuntu:/big/glib/x86/g_hash$

    三 测试例程2

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

    源码:main.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. void init_table(GHashTable *ht)
    7. {
    8. int i = 0;
    9. int ret = 0;
    10. char *key;
    11. char *value;
    12. for(int i = 0;i < 5;i++){
    13. key = malloc(10);
    14. sprintf(key,"hello%d",i);
    15. value = malloc(10);
    16. sprintf(value,"world%d",i);
    17. ret = g_hash_table_insert (ht,(gpointer)key,(gpointer)value);
    18. if(!ret){
    19. printf("insert error");
    20. exit(1);
    21. }
    22. }
    23. printf("init ok\n");
    24. }
    25. void show_keys(GHashTable *ht){
    26. GList* plist = g_hash_table_get_keys (ht);
    27. GList* list;
    28. int i = 0;
    29. for (list = plist; list != NULL; list = list->next)
    30. {
    31. printf("key%d = %s\n",i,(char*)list->data);
    32. i++;
    33. }
    34. printf("count = %d\n",i);
    35. printf("show_keys finish\n\n");
    36. }
    37. void show_table(GHashTable *ht)
    38. {
    39. GList* plist = g_hash_table_get_keys (ht);
    40. GList* list;
    41. int i = 0;
    42. gpointer value;
    43. for (list = plist; list != NULL; list = list->next)
    44. {
    45. value = g_hash_table_lookup (ht,(gpointer)list->data);
    46. printf("key = %s,value = %s\n",(char*)list->data,(char*)value);
    47. i++;
    48. }
    49. printf("count = %d\n",i);
    50. }
    51. void release_table(GHashTable *ht)
    52. {
    53. GList* plist = g_hash_table_get_keys (ht);
    54. GList* list;
    55. gpointer *value;
    56. for (list = plist; list != NULL; list = list->next)
    57. {
    58. value = g_hash_table_lookup (ht,(gpointer)list->data);
    59. g_hash_table_remove(ht,list->data);
    60. free(value);
    61. free(list->data);
    62. }
    63. printf("release_table finish\n\n");
    64. }
    65. void key_destroy_func(gpointer data)
    66. {
    67. printf("free %s\n",(char*)data);
    68. free(data);
    69. }
    70. void value_destroy_func(gpointer data)
    71. {
    72. printf("free %s\n",(char*)data);
    73. free(data);
    74. }
    75. gboolean
    76. key_equal_func (gconstpointer a,
    77. gconstpointer b)
    78. {
    79. if(strcmp(a,b) == 0){
    80. return TRUE;
    81. }
    82. return FALSE;
    83. }
    84. int main(int argc,char *argv[])
    85. {
    86. GHashTable *ht = g_hash_table_new_full(NULL,key_equal_func,
    87. key_destroy_func,value_destroy_func);
    88. init_table(ht);
    89. show_table(ht);
    90. show_keys(ht);
    91. char *new_value = malloc(5);
    92. sprintf(new_value,"new_str");
    93. show_table(ht);
    94. g_hash_table_remove_all(ht);
    95. return 0;
    96. }

    运行结果:

    1. lkmao@ubuntu:/big/glib/x86/g_hash$ ./app1
    2. init ok
    3. key = hello3,value = world3
    4. key = hello2,value = world2
    5. key = hello1,value = world1
    6. key = hello4,value = world4
    7. key = hello0,value = world0
    8. count = 5
    9. key0 = hello3
    10. key1 = hello2
    11. key2 = hello1
    12. key3 = hello4
    13. key4 = hello0
    14. count = 5
    15. show_keys finish
    16. key = hello3,value = world3
    17. key = hello2,value = world2
    18. key = hello1,value = world1
    19. key = hello4,value = world4
    20. key = hello0,value = world0
    21. count = 5
    22. free hello0
    23. free world0
    24. free hello4
    25. free world4
    26. free hello1
    27. free world1
    28. free hello2
    29. free world2
    30. free hello3
    31. free world3
    32. lkmao@ubuntu:/big/glib/x86/g_hash$

    结束

  • 相关阅读:
    WebSocket ----苍穹外卖day8
    C++中的赋值运算符重载和类的那点事
    CodeForces Round #829 (div.2) A~C2
    合并果子(C++)[堆]
    shell实现文件自动归档功能
    泽众云真机-平台即将升级支持华为机型HarmonyOS NEXT系统
    VMOS虚拟机开源,游戏安全面临新挑战
    抖音seo矩阵系统源代码分享
    离职前一定要做好这7件事情,少一件都很麻烦。
    sulfo-CY3(Cyanine3) DBCO,磺酸基-花青素CY5二苯并环辛炔,1782950-79-1
  • 原文地址:https://blog.csdn.net/yueni_zhao/article/details/127405446