GLib のハッシュテーブルを使う

APR のハッシュテーブルもよろしくね。

※ 2014-05-09 もっと色んな API を使ってみました。

C 言語には標準のハッシュテーブル (連想配列とか辞書ともいいます) がありません。しかし幸いなことに、GTK+ プロジェクトが開発している GLib という巨大なライブラリに各種コレクションが揃っています。これを使ってみましょう。

/*
 * coding: utf-8
 * ファイル名: g_hash.c
 */
#include
#include

void destroy_key (gpointer data);
void destroy_val (gpointer data);
void print_hash (gpointer key, gpointer value, gpointer user_data);

int
main (int argc, char *argv[])
{
  GHashTable *hash = g_hash_table_new_full (g_str_hash, g_str_equal,
      destroy_key, destroy_val);
  char *key;
  int *val;

  key = strdup ("りんご");
  val = g_new (int, 1);  /* sizeof (int) * 1 のメモリを割り当てます */
  *val = 100;
  g_hash_table_insert (hash, key, val);

  key = strdup ("いちご");
  val = g_new (int, 1);
  *val = 300;
  g_hash_table_insert (hash, key, val);

  g_print ("要素削除前\n"); /* printf と同じです */
  g_hash_table_foreach (hash, print_hash, NULL); /* 順序は不定です */

  g_print ("\n");

  g_hash_table_remove (hash, "いちご");
  g_print ("\n要素削除後\n");
  g_hash_table_foreach (hash, print_hash, NULL);

  g_print ("\n");
  g_hash_table_destroy (hash);

  return 0;
}

void
destroy_key (gpointer data) /* typedef void* gpointer; */
{
  g_print ("\"%s\" を free します\n", (char *) data);
  g_free (data);
}

void
destroy_val (gpointer data)
{
  g_print ("\"%d\" を free します\n", *(int *) data);
  g_free (data);
}

void
print_hash (gpointer key, gpointer value, gpointer user_data)
{
  g_print ("%s: %d 円\n", (char *) key, *(int *) value);
}

以下実行例です:

$ gcc -Wall -pedantic g_hash.c `pkg-config --cflags --libs glib-2.0`
$ ./a
要素削除前
りんご: 100 円
いちご: 300 円

"いちご" を free します
"300" を free します

要素削除後
りんご: 100 円

"りんご" を free します
"100" を free します

要素を削除するとコールバック関数を呼び出してくれるのがイカしてますね。なお、GINT_TO_POINTER マクロを使って int 値をポインタ型にキャストしてハッシュテーブルに保存することもできます。取り出す時は GPOINTER_TO_INT マクロを使います。これなら free する必要がありません。

API の詳細は http://developer.gnome.org/glib/2.30/glib-Hash-Tables.html を参照して下さい。

(コウヅ)


キャリアアップ

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中