用户空间不用自己编写数据结构,使用GLIB的工具是一个非常好的方式,下面的代码展示GLIB的链表的编程示例
#include
#include
#include
/*
* 需要安装
* yum install glib2-devel.x86_64
*
* 编译方法
* gcc glist_eg.c -g -O0 -lglib-2.0 -I /usr/include/glib-2.0/ `pkg-config --cflags glib-2.0` -o glist_eg
*/
void test1(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList* list = NULL;
list = g_slist_append(list, "second");
list = g_slist_prepend(list, "first");
g_printf("The list is now %d items long\n", g_slist_length(list));
list = g_slist_remove(list, "first");
g_printf("The list is now %d items long\n", g_slist_length(list));
g_slist_free(list);
printf("\n------------------------------------\n");
return ;
}
void test2(void){
GSList* list = NULL;
printf("\n--------------run %s ----------------\n", __FUNCTION__);
list = g_slist_append(list, "first");
list = g_slist_append(list, "second");
list = g_slist_append(list, "second");
list = g_slist_append(list, "third");
list = g_slist_append(list, "third");
g_printf("The list is now %d items long\n", g_slist_length(list));
list = g_slist_remove(list, "second");
list = g_slist_remove_all(list, "third");
g_printf("The list is now %d items long\n", g_slist_length(list));
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
void test3(void){
GSList* list = NULL;
printf("\n--------------run %s ----------------\n", __FUNCTION__);
list = g_slist_append(list, "first");
list = g_slist_append(list, "second");
list = g_slist_append(list, "third");
g_printf("The last item is '%s'\n", g_slist_last(list)->data);
g_printf("The item at index '1' is '%s'\n", g_slist_nth(list, 1)->data);
g_printf("Now the item at index '1' the easy way: '%s'\n", g_slist_nth_data(list, 1));
g_printf("And the 'next' item after first item is '%s'\n", g_slist_next(list)->data);
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
typedef struct st_person{
char name[10];
int shoe_size;
} Person;
void test4(void){
GSList* slist = NULL;
printf("\n--------------run %s ----------------\n", __FUNCTION__);
Person* tom = (Person*)malloc(sizeof(Person));
memset(tom, 0x0, sizeof(tom));
strcpy(tom->name, "Tom");
tom->shoe_size = 12;
slist = g_slist_append(slist, tom);
Person* fred = g_new0(Person, 1);
strcpy(fred->name, "Fred");
fred->shoe_size = 11;
slist = g_slist_append(slist, fred);
g_printf("Tom's shoe size is '%d'\n", ((Person*)slist->data)->shoe_size);
g_printf("Tom's shoe name is '%s'\n", ((Person*)(g_slist_nth(slist, 0)->data))->name);
g_printf("fred shoe size is '%d' \n", ((Person*)(g_slist_nth_data(slist,1)))->shoe_size);
g_printf("The last Person's name is '%s'\n", ((Person*)g_slist_last(slist)->data)->name);
/*注意释放链表并不会释放数据,需要手工进行*/
g_slist_free(slist);
free(tom);
g_free(fred);
printf("\n------------------------------------\n");
return;
}
void display_list(GSList *list)
{
GSList *iterator = NULL;
for (iterator = list; iterator; iterator = iterator->next) {
g_printf("%s ", (int*)iterator->data);
}
g_printf("\n");
}
void test5(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList* list1 = NULL;
list1 = g_slist_append(list1, "first");
list1 = g_slist_append(list1, "second");
GSList * list2 = NULL;
list2 = g_slist_append(list2, "third");
list2 = g_slist_append(list2, "fourth");
GSList * both = g_slist_concat(list1, list2); //连接两个表
display_list(both);
g_printf("The third item in the concatenated list is '%s'\n", g_slist_nth_data(both, 2));
GSList * reversed = g_slist_reverse(both); //反转一个表
g_printf("The first item in the reversed list is '%s'\n", reversed->data);
display_list(reversed);
g_slist_free(reversed);
printf("\n------------------------------------\n");
return;
}
void test6(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList * list = NULL;
GSList * iterator = NULL;
list = g_slist_append(list, "first");
list = g_slist_append(list, "second");
list = g_slist_append(list, "third");
for (iterator = list; NULL != iterator; iterator = iterator->next) {
g_printf("Current item is '%s'\n", iterator->data);
}
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
void print_iterator(gpointer item, gpointer prefix) {
g_printf("%s %s\n", prefix, item);
}
void print_iterator_short(gpointer item) {
g_printf("%s\n", item);
}
void test7(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList* list = g_slist_append(NULL, g_strdup("1"));
list = g_slist_append(list, g_strdup("2"));
list = g_slist_append(list, g_strdup("third"));
g_printf("Iterating with a function:\n");
/*
* 链表中的每个元素都调用上面的子函数 同时在每个输出前加“-->”
*/
g_slist_foreach(list, print_iterator, "-->");
g_printf("Iterating with a shorter function:\n");
g_slist_foreach(list, (GFunc)print_iterator_short, NULL);
g_printf("Now freeing each item\n");
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
gint my_comparator(gconstpointer item1, gconstpointer item2){
/*
* 比较两个条目,如果第一个条目小于第二个,则返回一个负值,如果相等则返回 0,如果第二个大于第一个则返回一个正值
* 这里可以自定义itme1和item2的大小比较函数
*/
return g_ascii_strcasecmp(item1, item2);
}
void test8(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList* list = g_slist_append(NULL, "Chicago");
list = g_slist_append(list, "Boston");
list = g_slist_append(list, "Albany");
/*按从小到大到数据进行排列*/
list = g_slist_sort(list, (GCompareFunc)my_comparator);
g_printf("The first item is now '%s'\n", list->data);
g_printf("The last item is now '%s'\n", g_slist_last(list)->data);
display_list(list);
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
gint my_finder(gconstpointer item) {
/*可以替换为自己的查找比较函数,注意返回值为int*/
return g_ascii_strcasecmp(item, "third");
}
void test9(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList* list = g_slist_append(NULL, "first");
list = g_slist_append(list, "second");
list = g_slist_append(list, "second.1");
list = g_slist_append(list, "third");
list = g_slist_append(list, "third.2");
g_printf("Show list'\n");
display_list(list);
/* 找到并删除节点 */
GSList* item = g_slist_find(list, "second");
g_printf("This should be the 'second' item: '%s'\n", item->data);
list = g_slist_remove_link(list, item);
g_slist_free_1(item);
item = NULL;
g_printf("Show list after g_slist_remove_link '\n");
display_list(list);
item = g_slist_find_custom(list, NULL, (GCompareFunc)my_finder);
g_printf("Again, this should be the 'second' item: '%s'\n", item->data);
list = g_slist_delete_link(list, item);
item = NULL;
g_printf("Show list after g_slist_delete_link '\n");
display_list(list);
/*找不到 item == NULL*/
item = g_slist_find(list, "delta");
g_printf("'delta' is not in the list, so we get: '%s'\n", item ? item->data : "(null)");
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
void test10(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GSList * list = g_slist_append(NULL, "Anaheim ");
GSList * iterator = NULL;
list = g_slist_append(list, "Elkton ");
g_printf("Before inserting 'Boston', second item is: '%s'\n", g_slist_nth(list, 1)->data);
g_slist_foreach(list, (GFunc)g_printf, NULL);
g_printf("\n");
list = g_slist_insert(list, "Boston ", 1);
g_printf("After insertion, second item is: '%s'\n", g_slist_nth(list, 1)->data);
g_slist_foreach(list, (GFunc)g_printf, NULL);
g_printf("\n");
list = g_slist_insert_before(list, g_slist_nth(list, 2), "Chicago ");
g_printf("After an insert_before, third item is: '%s'\n", g_slist_nth(list, 2)->data);
g_slist_foreach(list, (GFunc)g_printf, NULL);
g_printf("\n");
list = g_slist_insert_sorted(list, "Denver ", (GCompareFunc)g_ascii_strcasecmp);
g_printf("After inserting 'Denver', here's the final list:\n");
g_slist_foreach(list, (GFunc)g_printf, NULL);
g_printf("\n");
g_slist_free(list);
printf("\n------------------------------------\n");
return;
}
void test11(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GList* list = NULL;
list = g_list_append(list, "Austin ");
g_printf("The first item is '%s'\n", list->data);
list = g_list_insert(list, "Baltimore ", 1);
g_printf("The second item is '%s'\n", g_list_next(list)->data);
list = g_list_remove(list, "Baltimore ");
g_printf("After removal of 'Baltimore', the list length is %d\n", g_list_length(list));
GList* other_list = g_list_append(NULL, "Baltimore ");
list = g_list_concat(list, other_list);
g_printf("After concatenation: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
list = g_list_reverse(list);
g_printf("\nAfter reversal: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
g_list_free(list);
printf("\n------------------------------------\n");
return;
}
void test12(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GList* list = g_list_append(NULL, "Austin ");
list = g_list_append(list, "Bowie ");
list = g_list_append(list, "Charleston ");
g_printf("Here's the list: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
GList* last = g_list_last(list);
g_printf("\nThe first item (using g_list_first) is '%s'\n", g_list_first(last)->data);
g_printf("The prev-to-last item is '%s'\n", g_list_previous(last)->data);
g_printf("The prev-to-last item is '%s'\n", g_list_nth_prev(last, 1)->data);
g_list_free(list);
printf("\n------------------------------------\n");
return;
}
void test13(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GList* list = g_list_append(NULL, "Austin ");
list = g_list_append(list, "Bowie ");
list = g_list_append(list, "Chicago ");
g_printf("Here's the list: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
GList* bowie = g_list_nth(list, 1);
list = g_list_remove_link(list, bowie);
g_list_free_1(bowie);
g_printf("\nHere's the list after the remove_link call: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
list = g_list_delete_link(list, g_list_nth(list, 1));
g_printf("\nHere's the list after the delete_link call: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
g_list_free(list);
printf("\n------------------------------------\n");
return;
}
void test15(void){
printf("\n--------------run %s ----------------\n", __FUNCTION__);
GList* list = g_list_append(NULL, "Austin ");
list = g_list_append(list, "Bowie ");
list = g_list_append(list, "Bowie ");
list = g_list_append(list, "Cheyenne ");
g_printf("Here's the list: ");
g_list_foreach(list, (GFunc)g_printf, NULL);
g_printf("\nItem 'Bowie' is located at index %d\n", g_list_index(list, "Bowie "));
/*找不到的元素返回 -1 */
g_printf("Item 'Dallas' is located at index %d\n", g_list_index(list, "Dallas"));
GList* last = g_list_last(list);
g_printf("Item 'Cheyenne' is located at index %d \n", g_list_position(list, last));
g_list_free(list);
printf("\n------------------------------------\n");
return;
}
int main(int argc, char ** argv){
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
test15();
printf("hello world glist\n");
return 0;
}
编译方法
#注意需要提前按照 glib2-devel.x86_64的库
yum install glib2-devel.x86_64
gcc glist_eg.c -g -O0 -lglib-2.0 -I /usr/include/glib-2.0/ `pkg-config --cflags glib-2.0` -o glist_eg
程序输出
--------------run test1 ----------------
The list is now 2 items long
The list is now 1 items long
------------------------------------
--------------run test2 ----------------
The list is now 5 items long
The list is now 2 items long
------------------------------------
--------------run test3 ----------------
The last item is 'third'
The item at index '1' is 'second'
Now the item at index '1' the easy way: 'second'
And the 'next' item after first item is 'second'
------------------------------------
--------------run test4 ----------------
Tom's shoe size is '12'
Tom's shoe name is 'Tom'
fred shoe size is '11'
The last Person's name is 'Fred'
------------------------------------
--------------run test5 ----------------
first second third fourth
The third item in the concatenated list is 'third'
The first item in the reversed list is 'fourth'
fourth third second first
------------------------------------
--------------run test6 ----------------
Current item is 'first'
Current item is 'second'
Current item is 'third'
------------------------------------
--------------run test7 ----------------
Iterating with a function:
--> 1
--> 2
--> third
Iterating with a shorter function:
1
2
third
Now freeing each item
------------------------------------
--------------run test8 ----------------
The first item is now 'Albany'
The last item is now 'Chicago'
Albany Boston Chicago
------------------------------------
--------------run test9 ----------------
Show list'
first second second.1 third third.2
This should be the 'second' item: 'second'
Show list after g_slist_remove_link '
first second.1 third third.2
Again, this should be the 'second' item: 'third'
Show list after g_slist_delete_link '
first second.1 third.2
'delta' is not in the list, so we get: '(null)'
------------------------------------
--------------run test10 ----------------
Before inserting 'Boston', second item is: 'Elkton '
Anaheim Elkton
After insertion, second item is: 'Boston '
Anaheim Boston Elkton
After an insert_before, third item is: 'Chicago '
Anaheim Boston Chicago Elkton
After inserting 'Denver', here's the final list:
Anaheim Boston Chicago Denver Elkton
------------------------------------
--------------run test11 ----------------
The first item is 'Austin '
The second item is 'Baltimore '
After removal of 'Baltimore', the list length is 1
After concatenation: Austin Baltimore
After reversal: Baltimore Austin
------------------------------------
--------------run test12 ----------------
Here's the list: Austin Bowie Charleston
The first item (using g_list_first) is 'Austin '
The prev-to-last item is 'Bowie '
The prev-to-last item is 'Bowie '
------------------------------------
--------------run test13 ----------------
Here's the list: Austin Bowie Chicago
Here's the list after the remove_link call: Austin Chicago
Here's the list after the delete_link call: Austin
------------------------------------
--------------run test15 ----------------
Here's the list: Austin Bowie Bowie Cheyenne
Item 'Bowie' is located at index 1
Item 'Dallas' is located at index -1
Item 'Cheyenne' is located at index 3
------------------------------------
hello world glist
参考链接
https://developer.gnome.org/glib/stable/
https://developer.gnome.org/glib/stable/glib