glibc 函式庫

glibc 是 GNU 工具當中所提供的 C 語言函式庫,除了包含 ISO C 函式庫之外,glibc 還包含 POSIX (Portable Operating System Interface for Unix) 所定義的函數,POSIX 是 UNIX作業系統家族的標準介面,UNIX, Linux, Cygwin 等環境都支援 POSIX 標準,因此,glibc 的函數大部分都可以在這些平台上執行。

除此之外,glibc 還包含了一些其他平台中常見的好用函數,像是 Berkley Unix (BSD and SunOS) 的函數,UNIX System V Interface Description (SVID) 的函數,與 The X/Open Portability Guide 中的函數等等。表格 7.5顯示了 glibc 的標頭檔列表,僅供讀者參考。

表格 7.5 glibc函式庫的標頭檔分類表

ISO標準 說明 POSIX 標準 說明 其他檔頭 說明
assert.h 錯誤偵測 cpio.h 壓縮格式 argz.h 參數取得
complex.h 數學複數 dirent.h 目錄操作 envz.h 參數取得
ctype.h 字元處理 fcntl.h 檔案操作 execinfo.h 除錯堆疊
errno.h 錯誤處理 grp.h 群組管理 fnmatch.h 字串比對
fenv.h 浮點環境 pwd.h 帳號密碼 gconv.h 國際轉換
float.h 浮點數 sys/ipc.h 行程通訊 langinfo.h 格式轉換
inttypes.h 整數轉換 sys/msg.h 訊息佇列 mcheck.h 記憶體檢查
iso646.h 運算詞彙 sys/sem.h 號誌 ulimit.h 資源限制
limits.h 數值範圍 sys/stat.h 檔案資訊 utmp.h 使用者帳號
locale.h 國際化 sys/time.h 日期時間 obstack.h 物件堆疊
math.h 數學函數 sys/types.h 型態定義 printf.h 參數剖析
setjmp.h 遠程跳躍 sys/utsname.h 平台型號 regex.h 正規表示式
signal.h 引發錯誤 sys/wait.h 行程等待 search.h 排序搜尋
stdarg.h 變動參數 tar.h 壓縮格式 sys/param.h 系統參數
stdbool.h 布林型態 termios.h 終端機 sys/resource.h 系統資源
stddef.h 通用定義 unistd.h UNIX sys/stat.h 系統設定
stdint.h 整數型態 utime.h 檔案時間 sys/time.h 系統時間
stdio.h 輸出入 sys/types.h 系統型態
stdlib.h 一般函數 sys/utsname.h 系統名稱
string.h 字串處理 sys/vlimit.h 系統限制
tgmath.h 數學函數 sys/vtimes.h 系統時間
time.h 日期時間 sys/wait.h 行程等待
wchar.h Unicode sys/socket.h 網路函數
wctype.h Unicode netdb.h 網路資料
netinet/in.h 網路輸入
sys/un.h 網址

在glibc當中,補充了標準函式庫的一些不足之處,這包含二元樹 (Binary Tree)、赫序函數 (HashTable)、Unicode 字元處理函數、正規表示式、網路函式庫(Socket)、以及許多作業系統的相關函式庫等等,在本節中,我們將介紹glibc函式庫的一些常見用法,這些背景知識對於我們實作系統軟體時會有所幫助。

glibc 的二元樹與HashTable之使用方式

檔案:search.c                                             // 說明

#include <search.h>                                        // 引用檔案 search.h
#include <stdlib.h>                                        
#include <stdio.h>                                         

char *names[] = { "George", "Mary",                        // 宣告名單
"Bob", "Snoopy", "Mickey", "John", "Mike" };               

typedef struct {                                           // 宣告結構 person
  char *name;                                               
  int  id;                                                   
} person;                                                   

#define person_print(p) \                                  // 定義輸出函數
printf("id=%d name=%s\n", p->id, p->name)                   

int compare(const void *pa, const void *pb) {              // 定義比較函數
  person *p1=(person*)pa, *p2=(person*)pb;                   
  return strcmp(p1->name, p2->name);                       
}                                                           

void action(const void *nodep, const VISIT which,          // 定義節點訪問動作
            const int depth) {                               
  person *p;                                               
  switch(which) {                                           
    case preorder:                                           
      break;                                               
    case postorder:                                           
      p = *(person**)nodep;                                   
      person_print(p);                                       
      break;                                               
    case endorder:                                           
      break;                                               
    case leaf:                                               
      p = *(person**)nodep;                                   
      person_print(p);                                       
      break;                                               
  }                                                           
}                                                           

void binaryTreeTest() {                                    // 二元樹測試程式
  void *v, *root=NULL;                                     // 宣告根節點
  int i;                                                   
  for (i = 0; i < 7; i++) {                                // 將名單加入樹中
    person *p = (person*) malloc(sizeof(person));          // 分配空間
    p->name = strdup(names[i]);                            // 複製名稱
    p->id = i;                                             // 設定編號
    v = tsearch((void *)p, &root, compare);                // 新增p記錄
  }                                                           
  twalk(root, action);                                     // 列印整顆樹
}                                                           

void hashTableTest() {                                     // HashTable 測試程式
  void *v;                                                   
  int i;                                                   
  ENTRY e, *ep;                                               

  hcreate(30);                                             // 建立 hashTable
  for (i = 0; i < 5; i++) {                                // 將名單放入表格
    person *p = (person*) malloc(sizeof(person));          // 分配空間
    p->name = strdup(names[i]);                            // 複製名稱
    p->id = i;                                             // 設定編號
    e.key = p->name;                                       // 設定e=(key, data)
    e.data = p;                                               
    v = hsearch(e, ENTER);                                 // 新增e記錄
  }                                                           
  for (i=0; i<7; i++) {                                    // 從表格中取出名單
    e.key = names[i];                                      // 設定搜尋的 key
    ep = hsearch(e, FIND);                                 // 開始搜尋
    if (ep != NULL) {                                      // 如果有找到
      person *p = ep->data;                                //   取得 person
      person_print(p);                                     //   列印 person
    } else                                                 // 否則
      printf("%s not found !\n", e.key);                   //   印出找不到
  }                                                           
  hdestroy();                                              // 刪除 HashTable
}                                                           

int main() {                                               // 主程式
  printf("=====binaryTreeTest()=======\n");                   
  binaryTreeTest();                                        // 測試二元樹
  printf("=====hashTableTest()=======\n");                   
  hashTableTest();                                         // 測試 HashTable
  return 0;
}

執行過程與結果:

$ gcc search.c -o search

$ ./search
=====binaryTreeTest()=======
id=2 name=Bob
id=0 name=George
id=5 name=John
id=1 name=Mary
id=4 name=Mickey
id=6 name=Mike
id=3 name=Snoopy
=====hashTableTest()=======
id=0 name=George
id=1 name=Mary
id=2 name=Bob
id=3 name=Snoopy
id=4 name=Mickey
John not found !
Mike not found !
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License