原文地址:
http://oss.lzu.edu.cn/modules/newbb/viewtopic.php?topic_id=498&forum=13&move=next
参考地址:
http://hi.baidu.com/study_together/blog/item/efa7723a86d28ffe3b87ce3c.html
编译:gcc -g -Wall -O0 fuck.c -o fuck `pkg-config --libs --cflags glib-2.0`
1
创建、添加和销毁
下面的代码将初始化一个 GSList,向其添加两个条目,打印出列表的长度,然后释放它:
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
NULL;
printf(
"
The list is now %d items long\n
"
, g_slist_length(list));
list
=
g_slist_append(list,
"
first
"
);
list
=
g_slist_append(list,
"
second
"
);
printf(
"
The list is now %d items long\n
"
, g_slist_length(list));
g_slist_free(list);
return
0
;
}
***** Output *****
The list is now 0 items long
The list is now 2 items long
2
添加然后删除数据
可以添加数据;可能还会需要将其删除。这里是一个示例:
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
NULL;
list
=
g_slist_append(list,
"
second
"
);
list
=
g_slist_prepend(list,
"
first
"
);
printf(
"
The list is now %d items long\n
"
, g_slist_length(list));
list
=
g_slist_remove(list,
"
first
"
);
printf(
"
The list is now %d items long\n
"
, g_slist_length(list));
g_slist_free(list);
return
0
;
}
***** Output *****
The list is now 2 items long
The list is now 1 items long
3
删除重复的条目
这里是当在一个列表中有重复的条目时会发生的问题:
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
NULL;
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
"
);
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
"
);
printf(
"
The list is now %d items long\n
"
, g_slist_length(list));
g_slist_free(list);
return
0
;
}
***** Output *****
The list is now 5 items long
The list is now 2 items long
4
最后一个、第 n 个 和第 n 个数据
在 GSList 中有了一些条目后,可以通过不同的方式提取它们。这里是一些示例,并在 printf 语句中给出了解释。
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
NULL;
list
=
g_slist_append(list,
"
first
"
);
list
=
g_slist_append(list,
"
second
"
);
list
=
g_slist_append(list,
"
third
"
);
printf(
"
The last item is '%s'\n
"
, g_slist_last(list)
->
data);
printf(
"
The item at index '1' is '%s'\n
"
, g_slist_nth(list,
1
)
->
data);
printf(
"
Now the item at index '1' the easy way: '%s'\n
"
, g_slist_nth_data(list,
1
));
printf(
"
And the 'next' item after first item is '%s'\n
"
, g_slist_next(list)
->
data);
g_slist_free(list);
return
0
;
}
***** Output *****
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'
5
使用用户定义的类型
到现在为止我们一直在使用字符串;也就是说,我们只是将指向字符的指针放入到 GSList 中。在下面的代码示例中,
将会定义一个 Person 结构体,并将这个结构体的一些实例放入到 GSList 中:
#include
<
glib.h
>
#include
<
stdio.h
>
#include
<
stdlib.h
>
typedef
struct
{
char
*
name;
int
shoe_size;
} Person;
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
NULL;
Person
*
tom
=
(Person
*
)malloc(
sizeof
(Person));
tom
->
name
=
"
Tom
"
;
tom
->
shoe_size
=
12
;
list
=
g_slist_append(list, tom);
Person
*
fred
=
g_new(Person,
1
);
//
allocate memory for one Person struct
fred
->
name
=
"
Fred
"
;
fred
->
shoe_size
=
11
;
list
=
g_slist_append(list, fred);
printf(
"
Tom's shoe size is '%d'\n
"
, ((Person
*
)list
->
data)
->
shoe_size);
printf(
"
The last Person's name is '%s'\n
"
, ((Person
*
)g_slist_last(list)
->
data)
->
name);
g_slist_free(list);
free(tom);
g_free(fred);
return
0
;
}
***** Output *****
Tom's shoe size is '12'
The last Person's name is 'Fred'
6
组合、反转,等等
GSList 附带了一些便利的工具,可以连接和反转列表。这里是它们的工作方式:
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
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);
printf(
"
The third item in the concatenated list is '%s'\n
"
, g_slist_nth_data(both,
2
));
GSList
*
reversed
=
g_slist_reverse(both);
printf(
"
The first item in the reversed list is '%s'\n
"
, reversed
->
data);
g_slist_free(reversed);
return
0
;
}
***** Output *****
The third item in the concatenated list is 'third'
The first item in the reversed list is 'fourth'
7
简单遍历
这里是遍历 GSList 中所有内容的一个直观方法:
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
NULL,
*
iterator
=
NULL;
list
=
g_slist_append(list,
"
first
"
);
list
=
g_slist_append(list,
"
second
"
);
list
=
g_slist_append(list,
"
third
"
);
for
(iterator
=
list; iterator; iterator
=
iterator
->
next) {
printf(
"
Current item is '%s'\n
"
, iterator
->
data);
}
g_slist_free(list);
return
0
;
}
***** Output *****
Current item is 'first'
Current item is 'second'
Current item is 'third'
迭代器(iterator)
8
使用函数进行高级遍历
遍历列表的另一种方法是使用 g_slist_foreach,并提供一个将为列表中的每一个条目调用的函数。
#include
<
glib.h
>
#include
<
stdio.h
>
void
print_iterator(gpointer item, gpointer prefix) {
printf(
"
%s %s\n
"
, prefix, item);
}
void
print_iterator_short(gpointer item) {
printf(
"
%s\n
"
, item);
}
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
g_slist_append(NULL, g_strdup(
"
first
"
));
list
=
g_slist_append(list, g_strdup(
"
second
"
));
list
=
g_slist_append(list, g_strdup(
"
third
"
));
printf(
"
Iterating with a function:\n
"
);
g_slist_foreach(list, print_iterator,
"
-->
"
);
printf(
"
Iterating with a shorter function:\n
"
);
g_slist_foreach(list, (GFunc)print_iterator_short, NULL);
printf(
"
Now freeing each item\n
"
);
g_slist_foreach(list, (GFunc)g_free, NULL);
g_slist_free(list);
return
0
;
}
***** Output *****
Iterating with a function:
--> first
--> second
--> third
Iterating with a shorter function:
first
second
third
Now freeing each item
9
使用 GCompareFunc 排序
可以通过提供一个知道如何比较列表中条目的函数来对 GSLit 进行排序。下面的示例展示了对字符串列表进行排序的一种方法:
#include
<
glib.h
>
#include
<
stdio.h
>
gint my_comparator(gconstpointer item1, gconstpointer item2) {
return
g_ascii_strcasecmp(item1, item2);
}
int
main(
int
argc,
char
**
argv) {
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);
printf(
"
The first item is now '%s'\n
"
, list
->
data);
printf(
"
The last item is now '%s'\n
"
, g_slist_last(list)
->
data);
g_slist_free(list);
return
0
;
}
***** Output *****
The first item is now 'Albany'
The last item is now 'Chicago'
10
查找元素
有一些方法可以在 GSList 查找元素。已经介绍了如何简单地遍历列表的全部内容,比较每个条目,直到找到了目标条目。
如果已经拥有了要寻找的数据,而只是想要获得它在列表中的位置,那么可以使用 g_slist_find。最后,可以使用 g_slist_find_custom,
它允许您使用一个函数来检查列表中的每一个条目。下面展示了 g_slist_find 和 g_slist_find_custom:
#include
<
glib.h
>
#include
<
stdio.h
>
gint my_finder(gconstpointer item) {
return
g_ascii_strcasecmp(item,
"
second
"
);
}
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
g_slist_append(NULL,
"
first
"
);
list
=
g_slist_append(list,
"
second
"
);
list
=
g_slist_append(list,
"
third
"
);
GSList
*
item
=
g_slist_find(list,
"
second
"
);
printf(
"
This should be the 'second' item: '%s'\n
"
, item
->
data);
item
=
g_slist_find_custom(list, NULL, (GCompareFunc)my_finder);
printf(
"
Again, this should be the 'second' item: '%s'\n
"
, item
->
data);
item
=
g_slist_find(list,
"
delta
"
);
printf(
"
'delta' is not in the list, so we get: '%s'\n
"
, item
?
item
->
data :
"
(null)
"
);
g_slist_free(list);
return
0
;
}
***** Output *****
This should be the 'second' item: 'second'
Again, this should be the 'second' item: 'second'
'delta' is not in the list, so we get: '(null)'
11
通过插入进行高级添加
既然已经接触过几次 GCompareFunc,一些更有趣的插入操作会更有意义。使用 g_slist_insert 可以将条目插入到指定的位置,
使用 g_slist_insert_before 可以将条目插入到特定位置之前,使用 g_slist_insert_sorted 可以进行有序插入。这里是样例:
#include
<
glib.h
>
#include
<
stdio.h
>
int
main(
int
argc,
char
**
argv) {
GSList
*
list
=
g_slist_append(NULL,
"
Anaheim
"
),
*
iterator
=
NULL;
list
=
g_slist_append(list,
"
Elkton
"
);
printf(
"
Before inserting 'Boston', second item is: '%s'\n
"
, g_slist_nth(list,
1
)
->
data);
g_slist_insert(list,
"
Boston
"
,
1
);
printf(
"
After insertion, second item is: '%s'\n
"
, g_slist_nth(list,
1
)
->
data);
list
=
g_slist_insert_before(list, g_slist_nth(list,
2
),
"
Chicago
"
);
printf(
"
After an insert_before, third item is: '%s'\n
"
, g_slist_nth(list,
2
)
->
data);
list
=
g_slist_insert_sorted(list,
"
Denver
"
, (GCompareFunc)g_ascii_strcasecmp);
printf(
"
After inserting 'Denver', here's the final list:\n
"
);
g_slist_foreach(list, (GFunc)printf, NULL);
g_slist_free(list);
return
0
;
}
***** Output *****
Before inserting 'Boston', second item is: 'Elkton '
After insertion, second item is: 'Boston '
After an insert_before, third item is: 'Chicago '
After inserting 'Denver', here's the final list:
Anaheim Boston Chicago Denver Elkton
12
自定义数据结构排序 (根据字符)
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char* name;
int shoe_size;
} Person;
gint my_comparator(gconstpointer item1, gconstpointer item2) {
return g_ascii_strcasecmp(((Person*)item1)->name, ((Person*)item2)->name);
}
int main(int argc, char** argv) {
GSList* list = NULL;
Person* tom = (Person*)malloc(sizeof(Person));
tom->name = "Tom";
tom->shoe_size = 12;
list = g_slist_append(list, tom);
Person* fred = g_new(Person, 1); // allocate memory for one Person struct
fred->name = "Fred";
fred->shoe_size = 11;
list = g_slist_append(list, fred);
Person* god = g_new(Person, 1); // allocate memory for one Person struct
god->name = "zod";
god->shoe_size = 15;
list = g_slist_append(list, god);
list = g_slist_sort(list, (GCompareFunc)my_comparator);
printf("Tom's shoe size is '%d'\n", ((Person*)list->data)->shoe_size);
printf("The last Person's name is '%s'\n", ((Person*)g_slist_last(list)->data)->name);
g_slist_free(list);
free(tom);
g_free(fred);
g_free(god);
return 0;
}
***** Output *****
Tom's shoe size is '11'
The last Person's name is 'zod'
13 自定义数据结构排序(根据数字)
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char* name;
int shoe_size;
} Person;
gint my_comparator(gconstpointer item1, gconstpointer item2) {
if(((Person*)item1)->shoe_size > ((Person*)item2)->shoe_size)
{
return 1;
}
else
{
return 0;
}
// return g_ascii_strcasecmp(((Person*)item1)->name, ((Person*)item2)->name);
}
int main(int argc, char** argv) {
GSList* list = NULL;
Person* tom = (Person*)malloc(sizeof(Person));
tom->name = "Tom";
tom->shoe_size = 10;
list = g_slist_append(list, tom);
Person* fred = g_new(Person, 1); // allocate memory for one Person struct
fred->name = "yred";
fred->shoe_size = 11;
list = g_slist_append(list, fred);
Person* god = g_new(Person, 1); // allocate memory for one Person struct
god->name = "zod";
god->shoe_size = 15;
list = g_slist_append(list, god);
list = g_slist_sort(list, (GCompareFunc)my_comparator);
printf("Tom's shoe size is '%d'\n", ((Person*)list->data)->shoe_size);
printf("The last Person's name is '%s'\n", ((Person*)g_slist_last(list)->data)->name);
g_slist_free(list);
free(tom);
g_free(fred);
g_free(god);
return 0;
}
*******output*******
Tom's shoe size is '10'
The last Person's name is 'zod'
完