⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 book.html

📁 gtk_text program sample&eg
💻 HTML
📖 第 1 页 / 共 5 页
字号:
    {      *list_end = g_slist_append(*list_end, data)-&gt;next;    }} </pre><p> To use this function, you would store the list and its end somewhere, and pass their address to   <tt>efficient_append()</tt>:</p> <pre>  GSList* list = NULL;  GSList* list_end = NULL;  efficient_append(&amp;list, &amp;list_end, g_strdup("Foo"));  efficient_append(&amp;list, &amp;list_end, g_strdup("Bar"));  efficient_append(&amp;list, &amp;list_end, g_strdup("Baz"));</pre><p> Of course you have to be careful not to use any list functions that   might change the end of the list without updating <tt>list_end</tt>.</p> <p><table bgcolor="#EEEEFF" width="100%"><caption><b>Function Listing 2.8:</b> Changing linked list contents</caption><tr align="right"><td> <font color="black">&nbsp;<tt>#include &lt;glib.h&gt;</tt> </font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_append(GSList* list,               gpointer data)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_prepend(GSList* list,                gpointer data)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_insert(GSList* list,               gpointer data,               gint position)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_remove(GSList* list,               gpointer data)</pre></font> </td></tr></table></p><p> For accessing list elements, the functions in     Function Listing 2.9 are provided. None of these change     the list's structure. <tt>g_slist_foreach()</tt>     applies a <tt>GFunc</tt> to each element of the list. A <tt>GFunc</tt>     is defined as follows:</p> <pre>typedef void (*GFunc)(gpointer data, gpointer user_data);</pre><p> Used in <tt>g_slist_foreach()</tt>, your <tt>GFunc</tt> will be called on each <tt>list-&gt;data</tt> in <tt>list</tt>, passing the <tt>user_data</tt> you provided to <tt>g_slist_foreach()</tt>.   <tt>g_slist_foreach()</tt> is comparable to Scheme's   "map" function.</p> <p> For example, you might have a list of strings, and you might want to   be able to create a parallel list with some transformation applied   to the strings. Here is some code, using the   <tt>efficient_append()</tt> function from an   earlier example:</p> <pre>typedef struct _AppendContext AppendContext;struct _AppendContext {  GSList* list;  GSList* list_end;  const gchar* append;};static void append_foreach(gpointer data, gpointer user_data){  AppendContext* ac = (AppendContext*) user_data;  gchar* oldstring = (gchar*) data;  efficient_append(&amp;ac-&gt;list, &amp;ac-&gt;list_end,                    g_strconcat(oldstring, ac-&gt;append, NULL));}GSList*copy_with_append(GSList* list_of_strings, const gchar* append){  AppendContext ac;  ac.list = NULL;  ac.list_end = NULL;  ac.append = append;  g_slist_foreach(list_of_strings, append_foreach, &amp;ac);  return ac.list;}</pre><p> glib and Gtk+ use the "function pointer and user data" idiom       heavily. If you have functional programming experience, this        is much like using lambda expressions to create a       <i>closure</i>. (A closure combines a function with an       <i>environment</i>---a set of name-value bindings. In this case the       "environment" is the user data you pass to       <tt>append_foreach()</tt>, and the "closure" is the       combination of the function pointer and the user data.)</p> <p><table bgcolor="#EEEEFF" width="100%"><caption><b>Function Listing 2.9:</b> Accessing data in a linked list</caption><tr align="right"><td> <font color="black">&nbsp;<tt>#include &lt;glib.h&gt;</tt> </font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_find(GSList* list,             gpointer data)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_nth(GSList* list,            guint n)</pre></font> </td></tr><tr><td> <font color="black"><pre>gpointerg_slist_nth_data(GSList* list,                 guint n)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_last(GSList* list)</pre></font> </td></tr><tr><td> <font color="black"><pre>gintg_slist_index(GSList* list,              gpointer data)</pre></font> </td></tr><tr><td> <font color="black"><pre>voidg_slist_foreach(GSList* list,                GFunc func,                gpointer user_data)</pre></font> </td></tr></table></p><p> There are some handy list-manipulation routines, listed in     Function Listing 2.10.  With the exception of <tt>g_slist_copy()</tt>, all of these affect the lists in-place.  Which means you must assign the return value and forget about the passed-in pointer, just as you do when adding or removing list elements.  <tt>g_slist_copy()</tt> returns a newly-allocated list, so you can continue to use both lists and must free both lists eventually.</p> <p><table bgcolor="#EEEEFF" width="100%"><caption><b>Function Listing 2.10:</b> Manipulating a linked list</caption><tr align="right"><td> <font color="black">&nbsp;<tt>#include &lt;glib.h&gt;</tt> </font> </td></tr><tr><td> <font color="black"><pre>guintg_slist_length(GSList* list)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_concat(GSList* list1,               GSList* list2)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_reverse(GSList* list)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_copy(GSList* list)</pre></font> </td></tr></table></p><p> Finally, there are some provisions for sorted lists, shown in Function Listing 2.11. To use these, you must write a <tt>GCompareFunc</tt>, which is just like the comparison function in the standard C <tt>qsort()</tt>. Using glib types, this becomes:</p> <pre>typedef gint (*GCompareFunc) (gconstpointer a, gconstpointer b);</pre><p> If <tt>a &lt; b</tt>, the function should return a negative value; if <tt>a &gt; b</tt> a positive value; if <tt>a == b</tt> it should return 0.</p> <p> Once you have a comparison function, you can insert an element into an already-sorted list, or sort an entire list. Lists are sorted in ascending order.  You can even recycle your <tt>GCompareFunc</tt> to find list elements, using <tt>g_slist_find_custom()</tt>.  (A word of caution:    <tt>GCompareFunc</tt> is used inconsistently in glib; sometimes it      glib expects an equality predicate instead of a       <tt>qsort()</tt>-style function. However, the usage       is consistent within the list API.)</p> <p> Be careful with sorted lists; misusing them can rapidly become very   inefficient. For example,   <tt>g_slist_insert_sorted()</tt> is an O(n) operation,    but if you use it in a loop to insert multiple elements the    loop runs in exponential time. It's better to simply prepend    all your elements, then call <tt>g_slist_sort()</tt>.</p> <p><table bgcolor="#EEEEFF" width="100%"><caption><b>Function Listing 2.11:</b> Sorted lists</caption><tr align="right"><td> <font color="black">&nbsp;<tt>#include &lt;glib.h&gt;</tt> </font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_insert_sorted(GSList* list,                      gpointer data,                      GCompareFunc func)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_sort(GSList* list,             GCompareFunc func)</pre></font> </td></tr><tr><td> <font color="black"><pre>GSList*g_slist_find_custom(GSList* list,                    gpointer data,                    GCompareFunc func)</pre></font> </td></tr></table></p><h3>2.2.2:  Trees</h3><p> There are two different kinds of tree in glib; <tt>GTree</tt> is your basic balanced binary tree, useful to store key-value pairs sorted by key; <tt>GNode</tt> stores arbitrary tree-structured data, such as a parse tree or taxonomy.</p> <h4>GTree</h4><p> To create and destroy a <tt>GTree</tt>, use the     constructor-destructor pair displayed in     Function Listing 2.12.  <tt>GCompareFunc</tt> is the same     <tt>qsort()</tt>-style comparison function described     for <tt>GSList</tt>; in this case it's used to compare keys in the     tree.</p> <p><table bgcolor="#EEEEFF" width="100%"><caption><b>Function Listing 2.12:</b> Creating and destroying balanced binary trees</caption><tr align="right"><td> <font color="black">&nbsp;<tt>#include &lt;glib.h&gt;</tt> </font> </td></tr><tr><td> <font color="black"><pre>GTree*g_tree_new(GCompareFunc key_compare_func)</pre></font> </td></tr><tr><td> <font color="black"><pre>voidg_tree_destroy(GTree* tree)</pre></font> </td></tr></table></p><p> Functions for manipulating the contents of the tree are shown in  Function Listing 2.13. All very straightforward; <tt>g_tree_insert()</tt> overwrites any existing value, so be careful if the existing value is your only pointer to a chunk of allocated memory. If <tt>g_tree_lookup()</tt> fails to find the key, it returns <tt>NULL</tt>, otherwise it returns the associated value. Both keys and values have type <tt>gpointer</tt>, but the <tt>GPOINTER_TO_INT()</tt> and <tt>GPOINTER_TO_UINT()</tt> macros allow you to use integers instead.</p> <p><table bgcolor="#EEEEFF" width="100%"><caption><b>Function Listing 2.13:</b> Manipulating <tt>GTree</tt> contents</caption><tr align="right"><td> <font color="black">&nbsp;<tt>#include &lt;glib.h&gt;</tt> </font> </td></tr><tr><td> <font color="black"><pre>voidg_tree_insert(GTree* tree,              gpointer key,              gpointer value)</pre></font> </td></tr><tr><td> <font color="black"><pre>voidg_tree_remove(GTree* tree,              gpointer key)</pre></font> </td></tr><tr><td> <font color="black"><pre>gpointerg_tree_lookup(GTree* tree,              gpointer key)</pre></font> </td></tr>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -