typedefを用いた構造体定義についての補足

Copyright(C) 1July2008 coskx

構造体の定義とtypedefについて補足説明する。

1.typedef

「typedef」は変数の型を定義しなおす役割を果たす。List.1 は通常のdouble型の変数を用いて台形の面積を求めている。
これに対してList.2 はlength_t型とarea_t型の変数を用いているが,もともとはdouble型の変数であるため,関数printfの書式では「%f」を用いることになる。
しかし,文脈上はその変数の用途がよくわかるようになっている。

List 1 通常のdouble型の変数を用いて,台形の面積を求める

#include <stdio.h>

int main()
{
    double top, bottom, height; /*台形の上底,下底,高さ*/
    double area;                /*台形の面積*/
    top=10.0;      /*cm*/
    bottom=20.0;  /*cm*/
    height=10.0;   /*cm*/
    area=0.5*(top+bottom)*height;
    printf("top, bottom, height = %.1f, %.1f, %.1f\n",top, bottom, height);
    printf("area =%.1f\n",area);
    return 0;
}

実行結果

top, bottom, height = 10.0, 20.0, 10.0
area =150.0

List 2 length_t型とarea_t型の変数を用いて,台形の面積を求める

#include <stdio.h>

typedef double length_t;
typedef double area_t;

int main()
{
    length_t top, bottom, height; /*台形の上底,下底,高さ*/
    area_t area;                /*台形の面積*/
    top=10.0;      /*cm*/
    bottom=20.0;  /*cm*/
    height=10.0;   /*cm*/
    area=0.5*(top+bottom)*height;
    printf("top, bottom, height = %.1f, %.1f, %.1f\n",top, bottom, height);
    printf("area =%.1f\n",area);
    return 0;
}

実行結果

top, bottom, height = 10.0, 20.0, 10.0
area =150.0

この例は,あまり使われないだろう。ところが,構造体をtypedefで短く表現することはよくおこなわれる。

 

2.typedefを用いて構造体の変数宣言を短くする

本来の構造体の宣言方法は次のようになる。

struct タグ名 {
    要素1の宣言;
    要素2の宣言;
        :
};

例えば

struct point_type {
    int x; /*x座標*/
    int y; /*y座標*/
};

のように使う。

List 3 本来の構造体の宣言と変数宣言の例

#include <stdio.h>

/*stract point_type型の定義*/
struct point_type { /*←このpoint_typeがタグ名*/
    int x; /*x座標*/
    int y; /*y座標*/
};

struct point_type movePoint(struct point_type point, int dx, int dy)
{
    struct point_type newpoint;
    newpoint.x=point.x+dx;
    newpoint.y=point.y+dy;
    return newpoint;
}

int main()
{
    struct point_type pnt0={24,78};
    struct point_type pnt1;
    pnt1=movePoint(pnt0,10,-10);
    printf("pnt0=(%d,%d)\n",pnt0.x,pnt0.y);
    printf("pnt1=(%d,%d)\n",pnt1.x,pnt1.y);
    return 0;
}

実行結果

pnt0=(24,78)
pnt1=(34,68)

変数の宣言は

変数の型 変数名;

のように行われている。たとえば

int myvalue;
double myfvalue;

のように行われている。しかし,構造体の例では

struct point_type mypoint;

のようになり,変数の型を示す部分が2単語になってしまった。
そこでtypedefを用いることで,「struct point_type」を「point_t」の1単語であらわすことができるようになる。

List 4 typedefによる構造体の宣言と変数宣言の例

include <stdio.h>

/*stract point_type型の定義*/
typedef struct point_type { /*←このpoint_typeがタグ名*/
    int x; /*x座標*/
    int y; /*y座標*/
}
point_t;

point_t movePoint(point_t point, int dx, int dy)
{
    point_t newpoint;
    newpoint.x=point.x+dx;
    newpoint.y=point.y+dy;
    return newpoint;
}

int main()
{
    point_t pnt0={24,78};
    point_t pnt1;
    pnt1=movePoint(pnt0,10,-10);
    printf("pnt0=(%d,%d)\n",pnt0.x,pnt0.y);
    printf("pnt1=(%d,%d)\n",pnt1.x,pnt1.y);
    return 0;
}

実行結果

pnt0=(24,78)
pnt1=(34,68)

構造体定義にtypedefを使った場合

typedef struct point_type {
    int x; /*x座標*/
    int y; /*y座標*/
} point_t;

struct point_type {
    int x; /*x座標*/
    int y; /*y座標*/
}


point_t型として今後使いますという意味になる。

 

3.typedefを用いた構造体の宣言でタグ名を省略する

タグ名は使われないため省略される場合が多い。

List 5 typedefによる構造体の宣言と変数宣言の例(タグ名省略)

#include <stdio.h>

/*stract point_type型の定義*/
typedef
struct { /*ここにタグ名が省略されている*/
    int x; /*x座標*/
    int y; /*y座標*/
}
point_t;

point_t movePoint(point_t point, int dx, int dy)
{
    point_t newpoint;
    newpoint.x=point.x+dx;
    newpoint.y=point.y+dy;
    return newpoint;
}

int main()
{
    point_t pnt0={24,78};
    point_t pnt1;
    pnt1=movePoint(pnt0,10,-10);
    printf("pnt0=(%d,%d)\n",pnt0.x,pnt0.y);
    printf("pnt1=(%d,%d)\n",pnt1.x,pnt1.y);
    return 0;
}

実行結果

pnt0=(24,78)
pnt1=(34,68)

 

4.typedefを用いた構造体の宣言でタグ名が省略できない例

この 構造体タグ名を省略できない場合もある。リスト構造の要素構造体などでは構造体のポインタを構造体要素に持つ。C言語では,使用する名前は事前に定義されていなければならないので,構造体タグ名は必須となる。

typedef struct point_type {
    int x; /*x座標*/
    int y; /*y座標*/
    point_type *ptrpoint; /*自分とおなじ構造体を指すポインタ*/
} point_t;

使用する名前は事前に定義されていなければならないので次のようには書けない

typedef struct { /*コンパイルエラーになる例*/
    int x; /*x座標*/
    int y; /*y座標*/
    point_t *ptrpoint; /*自分とおなじ構造体を指すポインタを宣言したかったが*/
} point_t;