C指针原理(39)-GLIB
一、簡述與配置
GLib是一個跨平臺的、用C語言編寫的庫,起初是GTK+的一部分,但到了GTK+第二版,開發者決定把跟圖形界面無關的代碼分開,這些代碼于是就組裝成了GLib。因為GLib具有跨平臺特性,所以用它編寫的程序可以無需進行大幅度修改就可以在其他程序上編譯和運行。
glib庫是Linux平臺下最常用的C語言函數庫,它具有很好的可移植性和實用性。
glib是Gtk +庫和Gnome的基礎。glib可以在多個平臺下使用,比如Linux、Unix、Windows等。glib為許多標準的、常用的C語言結構提供了相應的替代物。
如果在程序中要使用到glib庫中的函數,則應該包含glib.h頭文件(在gtk.h和gnome.h頭文件中已經包含了glib.h了)
1、Freebsd中安裝glib
cd /usr/ports/devel/glib20
portsnap fetch extract
Looking up portsnap.FreeBSD.org mirrors… 7 mirrors found.
Fetching snapshot tag from isc.portsnap.freebsd.org… done.
Fetching snapshot metadata… done.
Updating from Fri Dec 6 11:20:31 CST 2013 to Mon Dec 23 21:23:19 CST 2013.
Fetching 4 metadata patches… done.
Applying metadata patches… done.
Fetching 4 metadata files… gunzip: (stdin): unexpected end of file
metadata is corrupt.
root@dp:/usr/ports/devel/glib20 # ls
Makefile distinfo files pkg-descr pkg-plist
root@dp:/usr/ports/devel/glib20 # make install clean
===> License LGPL20 accepted by the user
===> Found saved configuration for glib-2.36.3
===> Fetching all distfiles required by glib-2.36.3 for building
===> Extracting for glib-2.36.3
=> SHA256 Checksum OK for gnome2/glib-2.36.3.tar.xz.
===> Patching for glib-2.36.3
===> glib-2.36.3 depends on package: libtool>=2.4 - found
===> Applying FreeBSD patches for glib-2.36.3
…
…
2、windows下配置與安裝
3、測試:
Linux/unix下測試,以freebsd為例
首先看一下下面這個程序,在編輯器中輸入下面程序,程序首先創建20個1-100以內的隨機數,并顯示在屏幕,然后計算30000000次累加,并輸出計算用的時間。
#include <glib.h>
int main(int argc, char *argv[])
{
GRand *rand;
GTimer *timer;
gint n;
gint i, j;
gint x = 0;
rand = g_rand_new(); //創建隨機數對象
for(n=0; n<20; n++)
{ //產生隨機數并顯示出來
g_print("%d\t",g_rand_int_range(rand,1,100));
}
g_print("\n");
g_rand_free(rand); //釋放隨機數對象
//創建計時器
timer = g_timer_new();
g_timer_start(timer);//開始計時
for(i=0; i<10000; i++)
for(j=0; j<3000; j++)
x++;//累計
g_timer_stop(timer);//計時結束
//輸出計時結果
g_print("%ld\tall:%.2f seconds was used!\n",x,g_timer_elapsed(timer,NULL));
}
編譯
dp@dp:~/gliblearn % gcc pkg-config --cflags --libs glib-2.0 gthread-2.0 a.c -o mytest
最后執行:
dp@dp:~/gliblearn % ./mytest
96 24 52 87 52 16 62 17 78 62 76 6 33 53 87 3 40 69 20 33
30000000 all:0.08 seconds was used!
dp@dp:~/gliblearn %
二、21點游戲
1、游戲規則:
隨機抽取1-11個數字,每次玩家和電腦各抽1次,玩家和電腦可以宣布不再抽數字,所有數字之和超過21點者輸,在21點以內,大者勝利。
(1)歡迎玩家
使用gchar字符型來存儲玩家姓名。
typedef char gchar;
編寫代碼如下:
#include <glib.h>
#include <stdio.h>
#include <locale.h>
int main(int argc, char *argv[]){
setlocale(LC_ALL,"");
gchar gamename[10];
g_print(“您叫什么名字?\n”);
scanf("%s",&gamename);
g_print(“歡迎您,%s,這里是21點游戲\n”,gamename);
return 0;
}
dp@dp:~/gliblearn % gcc pkg-config --cflags --libs glib-2.0 gthread-2.0 1.c -o mytest
dp@dp:~/gliblearn % ./mytest
您叫什么名字?
joan
歡迎您,joan,這里是21點游戲!
dp@dp:~/gliblearn %
(2)引入隨機數
使用glib的隨機數函數產生隨機數
gamerand = g_rand_new();
rndnumber=g_rand_int_range(gamerand,1,11);
程序如下:
#include <glib.h>
#include <stdio.h>
#include <locale.h>
int main(int argc, char *argv[]){
setlocale(LC_ALL,"");
GRand *gamerand;
gchar gamename[10];
g_print(“您叫什么名字?\n”);
scanf("%s",&gamename);
g_print(“歡迎您,%s,這里是21點游戲\n”,gamename);
g_print("%s,請按鍵抽數字!\n",gamename);
getchar();
getchar();
gint rndnumber;
gamerand = g_rand_new();
rndnumber=g_rand_int_range(gamerand,1,11);
g_print("%s,您抽到的是:%d\n",gamename,rndnumber);
g_rand_free(gamerand);
return 0;
}
dp@dp:~/gliblearn % ./mytest
您叫什么名字?
joan
歡迎您,joan,這里是21點游戲
joan,請按鍵抽數字!
joan,您抽到的是:3
dp@dp:~/gliblearn %
(3)輪流抽數判斷輸贏
使用邏輯型變量類型gboolean,定義如下:
typedef gint gboolean;
A standard boolean type. Variables of this type should only contain the value TRUE or FALSE.
代碼如下:
dp@dp:~/gliblearn % cat 21dian.c
#include <glib.h>
#include <stdio.h>
#include <locale.h>
int main(int argc, char *argv[]){
setlocale(LC_ALL,"");
GRand *gamerand;
gchar gamename[10];
g_print(“您叫什么名字?\n”);
scanf("%s",&gamename);
g_print(“歡迎您,%s,這里是21點游戲\n”,gamename);
setbuf(stdin,NULL);
gint key=0;
gint rndnumber;
gint man_number,comp_number;
gint man_count=0,comp_count=0;
gboolean man_end=FALSE,comp_end=FALSE;
gboolean gameover=FALSE;
gamerand = g_rand_new();
do{
if (!man_end){
g_print("%s,按Y/y鍵抽數字,按其它鍵表示不再抽數字!\n",gamename);
key=getchar();
getchar();
//玩家抽數字
if (key==‘y’||key==‘Y’){
rndnumber=g_rand_int_range(gamerand,1,11);
man_number=rndnumber;
man_count+=man_number;
g_print("%s,您抽到的是:%d\n",gamename,man_number);
}else
{
g_print(“玩家放棄抽數!\n”,comp_number);
man_end=TRUE;
}
}//電腦抽數字
if (comp_count<=17){
rndnumber=g_rand_int_range(gamerand,1,11);
comp_number=rndnumber;
comp_count+=comp_number;
g_print(“電腦抽到的是:%d\n”,comp_number);
}else
{
g_print(“電腦放棄抽數!\n”,comp_number);
comp_end=TRUE;
}
if ((man_count>21 && comp_count>21)||(man_count21 && comp_count21)){
g_print(“平手,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;
}
else if (man_count>21 && comp_count<=21) {
g_print(“電腦贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;
}
else if (man_count<=21 && comp_count>21) {
g_print(“玩家贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
break;
}else if (man_end && comp_end){
man_count>comp_count?g_print(“玩家贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count):g_print(“電腦贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;}else
{
g_print("\n$$$$本輪結束,電腦本輪結束,電腦%d點,%s %d點本輪結束,電腦$$$$\n",comp_count,gamename,man_count);
}
}while(!gameover);
g_rand_free(gamerand);
return 0;
}
編譯執行:
dp@dp:~/gliblearn % gcc pkg-config --cflags --libs glib-2.0 gthread-2.0 21dian.c -o 21dian
dp@dp:~/gliblearn % ./21dian
您叫什么名字?
joan
歡迎您,joan,這里是21點游戲
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
y
joan,您抽到的是:7
電腦抽到的是:10
$$$$本輪結束,電腦10點,joan7點本輪結束,電腦10點,joan 7點本輪結束,電腦10點,joan7點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
Y
joan,您抽到的是:1
電腦抽到的是:9
$$$$本輪結束,電腦19點,joan8點本輪結束,電腦19點,joan 8點本輪結束,電腦19點,joan8點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
Y
joan,您抽到的是:10
電腦放棄抽數!
$$$$本輪結束,電腦19點,joan18點本輪結束,電腦19點,joan 18點本輪結束,電腦19點,joan18點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
Y
joan,您抽到的是:7
電腦放棄抽數!
電腦贏了,電腦19點,joan 25點
dp@dp:~/gliblearn % ./21dian
您叫什么名字?
joan
歡迎您,joan,這里是21點游戲
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
y
joan,您抽到的是:2
電腦抽到的是:8
$$$$本輪結束,電腦8點,joan2點本輪結束,電腦8點,joan 2點本輪結束,電腦8點,joan2點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
y
joan,您抽到的是:2
電腦抽到的是:3
$$$$本輪結束,電腦11點,joan4點本輪結束,電腦11點,joan 4點本輪結束,電腦11點,joan4點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
y
joan,您抽到的是:5
電腦抽到的是:5
$$$$本輪結束,電腦16點,joan9點本輪結束,電腦16點,joan 9點本輪結束,電腦16點,joan9點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
y
joan,您抽到的是:2
電腦抽到的是:9
玩家贏了,電腦25點,joan 11點
dp@dp:~/gliblearn %
三、Glib的數據類型及標準宏
1、GLib數據類型
類型 描述gboolean
由于c語言沒有提供布爾數據類型,所以Glib提供了gboolean,可以設置為TRUE或FALSE。
gchar (guchar)
和標準C的char(unsigned char)類型一致。
gconstpointer
一個指向常量的無類型指針。這種指針指向的數據不能改變。因此,它通常用于函數原型,表明這個函數不會改變該指針指向的數據。
gdouble
與標準C的double類型一致。取值范圍從-G_MAXDOUBLE到G_MAXDOUBEL。G_MINDOUBLE指的是gdouble可以儲存的最小正數。
gfloat
與標準C的float類型一致。可能的的取值范圍從-G_MAXFLOAT到G_MAXFLOAT。G_MINFLOAT指的是gfloat可以儲存的最小正數。
gint (guint)
和標準C的int(unsigned int)類型一致。有符號的gint類型的值必須在G_MININT到G_MAXINT的范圍內。guint的最大值為G_MAXUINT.
gint8 (guint8)
被設計為在所有平臺上都為8位的有符號和無符號整型。gint8的取值范圍為-128到127(G_MININT8到G_MAXINT8),guint8的取值范圍為0到255(G_MAXUINT8)。
gint16 (guint16)
被設計為在所有平臺上都為16位的有符號和無符號整型。gint16取值范圍為-32768到32767(G_MININT16到G_MAXINT16),guint16的取值范圍為0到65535(G_MAXUINT16)。
gint32 (guint32)
被 設計為在所有平臺上都為32位的有符號和無符號整型。gint32取值范圍為-2,147,483,648到 2,147,483,647(G_MININT32到G_MAXINT32),guint32的取值范圍為0到 4,294,967,295(G_MAXUINT32)。
gint64 (guint64)
被設計為在所有平臺上都為64位的有符號和無符號整型。gint64取值范圍為-263次方到263-1(G_MININT64到G_MAXINT64),guint64的取值范圍為0到2^64-1(G_MAXUINT64)。
glong (gulong)
和標準C的long(unsigned long)類型一致。glong的取值范圍從G_MINLONG到G_MAXLONG。gulong的最大值為G_MAXULONG.
gpointer
一個定義為void的無類型指針。只是為了看上去比標準的void好看。
gshort(gushort)
和標準C的short(unsigned short)類型一致。glong的取值范圍從G_MINSHORT到G_MAXSHORT。gushort的最大值為G_MAXUSHORT。
gsize(gssize)
無符號和有符號的32位整型。在許多數據結構中用來代表大小。gsize被定義為unsigned int,gssize被定義為signed int。
2、標準Glib宏
宏 描述ABS(a)
返回a的絕對值。這個宏只是簡單的返回去掉符號的負數,對正數不進行任何操作。
CLAMP(a,low,high)
確認a是否在low和high之間。如果a不再low和high之間,將會返回與low和high之間與a比較接近的那個。否則返回a。
G_DIR_SEPARATOR G_DIR_SEPARATOR_S
在UNIX系統中,目錄用斜杠(/)來分隔,在Windows系統中,用的是反斜杠(),G_DIR_SEPARATOR以字符類型返回一個適當的分隔符,而G_DIR_SEPARATOR_S返回的是一個字符串。
GINT_TO_POINTER(i) GPOINTER_TO_INT§
將一個gpointer轉換成一個整數,或將一個整數轉換成一個gpointer。整數中只有32位將會被儲存。你一定要避免對占用空間超過32位的整數使用這些宏。記住你不能在整數中儲存指針,這些宏僅僅是允許你以指針的形式儲存整數。
GSIZE_TO_POINTER(s) GPOINTER_TO_SIZE§
把gsize轉換成gpointer或者把gpointer轉換成gsize。如果想把gsize的值從指針轉換回來,它事先必須已經通過GSIZE_TO_POINTER()被儲存為指針,請參見GINT_TO_POINTER()。
GUINT_TO_POINTER(u) GPOINTER_TO_UINT§
把一個無符號整數轉換成gpointer,或者把gpointer轉換成無符號整數。如果想把整數從指針轉換回來,它事先必須已經通過GUINT_TO_POINTER()被儲存為指針,請參見GINT_TOOPOINTER()。
G_OS_WIN32 G_OS_BEOS G_OS_UNIX
這三個宏允許你定義只能運行在特定平臺的代碼。只有和用戶使用的操作系統一致的那個宏會被定義,所以你可以用#ifdef GOS*來寫只能用于用戶的平臺的代碼。
G_STRUCT_MEMBER_P(struct_p, offset)
返回一個指向在結構體內偏移量為offset的成員的無類型指針,偏移量必須在struct_p的范圍之內。
G_STRUCT_OFFSET(type, member)
返回一個成員在結構體內的偏移量。type指明結構體的類型。
MIN(a, b) MAX(a, b)
計算兩個a和b中的最小值和最大值。
TRUE 和 FALSE
FALSE被定義為0,TRUE為FALSE的邏輯非。這兩個值被gboolean所使用。
四、改造21點游戲
1、引入字符串類型
GString結構包含了三個成員:保存字符串當前狀態的C字符串,除了結束符的字符串長度,和為字符串當前分配的內存數量。如果字符串增加到超出分配的內存長度,GString會自動為其分配更多內存。
typedef struct{gchar *str;gsize len;gsize allocated_len;} GString;四、改造21點游戲1、引入字符串類型
GString結構包含了三個成員:保存字符串當前狀態的C字符串,除了結束符的字符串長度,和為字符串當前分配的內存數量。如果字符串增加到超出分配的內存長度,GString會自動為其分配更多內存。
typedef struct{gchar *str;gsize len;gsize allocated_len;} GString;在玩家和電腦抽數后,僅顯示本次抽到的數字,需要在每次抽取后顯示所有的數字,使用Gstring完成含有多個數字的字符串的動態生成。創建一個新GString的一種方式是利用g_string_new(),使用g_string_append_printf(),它將附加格式化的字符串到GString的結尾,并保持當前內容不變。
dp@dp:~/gliblearn % cat 21dian.c
#include <glib.h>
#include <stdio.h>
#include <locale.h>
//code:joan@joan.com
//date:2014-01-26
//未經作者書面許可,請勿用于任何用途
int main(int argc, char *argv[]){
setlocale(LC_ALL,"");
GString *man_list;
GString *comp_list;
man_list=g_string_new("玩家抽到的數字: ");
comp_list=g_string_new("電腦抽到的數字: ");
GRand *gamerand;
gchar gamename[10];
g_print("您叫什么名字?\n");scanf("%s",&gamename);
g_print(“歡迎您,%s,這里是21點游戲\n”,gamename);
setbuf(stdin,NULL);
gint key=0;
gint rndnumber;
gint man_number,comp_number;
gint man_count=0,comp_count=0;
gboolean man_end=FALSE,comp_end=FALSE;
gboolean gameover=FALSE;
gamerand = g_rand_new();
do{
if (!man_end){
g_print("%s,按Y/y鍵抽數字,按其它鍵表示不再抽數字!\n",gamename);
key=getchar();
getchar();
//玩家抽數字
if (key==‘y’||key==‘Y’){
rndnumber=g_rand_int_range(gamerand,1,11);
man_number=rndnumber;
man_count+=man_number;
g_string_append_printf(man_list,"%d ",man_number);
g_print("%s,您抽到的是:%d\n",gamename,man_number);
}else
{
g_print(“玩家放棄抽數!\n”,comp_number);
man_end=TRUE;
}
}//電腦抽數字
if (comp_count<=17){
rndnumber=g_rand_int_range(gamerand,1,11);
comp_number=rndnumber;
comp_count+=comp_number;
g_string_append_printf(comp_list,"%d ",comp_number);
g_print(“電腦抽到的是:%d\n”,comp_number);
}else
{
g_print(“電腦放棄抽數!\n”,comp_number);
comp_end=TRUE;
}
g_print("$$$$本輪結束,雙方明細本輪結束,雙方明細本輪結束,雙方明細$$$$\n");
g_print("%s\n",man_list->str);
g_print("%s\n",comp_list->str);
if ((man_count>21 && comp_count>21)||(man_count<=21 && comp_count<=21 && man_count==comp_count && man_end &&comp_end)){
g_print(“平手,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;
}
else if ((man_count>21 && comp_count<=21)||(man_count<21 && comp_count==21)) {
g_print(“電腦贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;
}
else if ((man_count<=21 && comp_count>21) ||(man_count==21 && comp_count<21)) {
g_print(“玩家贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;
}
else if (man_end && comp_end){
man_count>comp_count?g_print(“玩家贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count):g_print(“電腦贏了,電腦%d點,%s %d點\n”,comp_count,gamename,man_count);
gameover=TRUE;}
else
{
g_print("\n$$$$電腦電腦%d點,%s %d點電腦$$$$\n",comp_count,gamename,man_count);
}
}while(!gameover);
g_string_free(man_list,TRUE);
g_string_free(comp_list,TRUE);
g_rand_free(gamerand);
return 0;
}
dp@dp:~/gliblearn % ./21dian
您叫什么名字?
joan
歡迎您,joan,這里是21點游戲
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
y
joan,您抽到的是:8
電腦抽到的是:8
$$$$本輪結束,雙方明細本輪結束,雙方明細本輪結束,雙方明細$$$$
玩家抽到的數字: 8
電腦抽到的數字: 8
$$$$電腦8點,joan8點電腦8點,joan 8點電腦8點,joan8點$$$$
joan,按Y/y鍵抽數字,按其它鍵表示不再抽數字!
n
玩家放棄抽數!
電腦抽到的是:1
$$$$本輪結束,雙方明細本輪結束,雙方明細本輪結束,雙方明細$$$$
玩家抽到的數字: 8
電腦抽到的數字: 8 1
$$$$電腦9點,joan8點電腦9點,joan 8點電腦9點,joan8點$$$$
電腦抽到的是:7
$$$$本輪結束,雙方明細本輪結束,雙方明細本輪結束,雙方明細$$$$
玩家抽到的數字: 8
電腦抽到的數字: 8 1 7
$$$$電腦16點,joan8點電腦16點,joan 8點電腦16點,joan8點$$$$
電腦抽到的是:2
$$$$本輪結束,雙方明細本輪結束,雙方明細本輪結束,雙方明細$$$$
玩家抽到的數字: 8
電腦抽到的數字: 8 1 7 2
$$$$電腦18點,joan8點電腦18點,joan 8點電腦18點,joan8點$$$$
電腦放棄抽數!
$$$$本輪結束,雙方明細本輪結束,雙方明細本輪結束,雙方明細$$$$
玩家抽到的數字: 8
電腦抽到的數字: 8 1 7 2
電腦贏了,電腦18點,joan 8點
總結
以上是生活随笔為你收集整理的C指针原理(39)-GLIB的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab矢量角度,MATLAB矢量,
- 下一篇: C指针原理(40)-递归(1)