typedef による構造体のユーザー定義型の宣言方法

typedef 指定子を使うと、わかりやすい型名を自由に付けることができます。

typedef は特に構造体を使うときに便利なので、よく使われます。 書かれていたときに読めて意味がわかるだけでなく、自分でも書けるようになるとよいでしょう。

まずは typedef を使わない場合の構造体の使い方からみていきましょう。

typedef を使わない場合

構造体は struct で宣言します。具体例として person という名前で、nameage の二つのメンバーをもつ構造体を考えてみましょう。

次を test.h とします。

#ifndef TEST_H_
#define TEST_H_

struct person {
  char name[40];
  int age;
};

#endif /* TEST_H_ */

これを使うところでは、次のように struct person として使います。

#include <stdio.h>
#include <stdlib.h>
#include "test.h"

int main() {
  struct person p;
  snprintf(p.name, sizeof(p.name), "Ichiro Yamda");
  p.age = 30;
  printf("%s (%d)\n", p.name, p.age);
  return 0;
}

実行すると次のように出力されるはずです。

Ichiro Yamda (30)

動作するのは当たり前で結構なことなのですが、通常、ビルトインの型は int とか char とか 1 語で書くものなので、 このように 2 語になるのはパッと見て、変数名であるようにも見えて厄介な感じがします。

そういう事情があって、構造体や共用体と組み合わせて typedef が使われることがよくあります。

typedef を使った場合

では、typedef を使う典型的な例を紹介します。

先ほどの構造体の宣言は、次のように書くことが多いです。

#ifndef TEST_H_
#define TEST_H_

typedef struct _PERSON {
  char name[40];
  int age;
} PERSON, *PPERSON;

#endif /* TEST_H_ */

これで struct キーワードなしで PERSON という型が使えるようになります。

ここではついでに、PERSON へのポインター型として PPERSON というユーザー定義型も宣言してます。こういう書き方もよくやるので、覚えておくと良いです。

例えば Eclipse CDT などでも、ちゃんと二つとも認識しています。

使い方をみてみましょう。

test.c は次のように書き換えられます。

#include <stdio.h>
#include <stdlib.h>
#include "test.h"

int main() {
  PERSON p;
  snprintf(p.name, sizeof(p.name), "Ichiro Yamda");
  p.age = 30;
  printf("%s (%d)\n", p.name, p.age);
  return 0;
}

もちろん、実行結果は上と同じです。

ポインター版の型として宣言した PPERSON を使う場合は、次のようになります。

#include <stdio.h>
#include <stdlib.h>
#include "test.h"

int main() {
  PPERSON pp;
  pp = (PPERSON) calloc(1, sizeof(PERSON));

  if (!pp) {
    fprintf(stderr, "Unable to allocate memory.");
    return 1;
  }

  snprintf(pp->name, sizeof(pp->name), "Hanako Yamda");
  pp->age = 20;
  printf("%s (%d)\n", pp->name, pp->age);
  free(pp);
  return 0;
}

calloc でヒープからメモリを取ったので、少しコードが長くなっています。

実行結果は次の通りです。

Hanako Yamda (20)

以上、typedef による構造体のユーザー定義型の宣言方法について典型的な方法を説明しました。