typedefで型に別名を付ける

こんにちは、めのんです!

予告通りにいかないことが多くて申し訳ありません。
前回、次は割付け記憶域期間について書くと予告しましたが、typedefのことを先に解説しますね。
ちょっと間が空くので「その間もなるべく別の話題を投稿します」とも書きましたので、そういうことで。

型に別名を付ける

これまで登場したsize_t型やptrdiff_t型などは、int型やdouble型のようなCがはじめから持っている型ではありません。
じゃあ一体何かというと、もともとある型に別名を付けたものです。
具体的にどんな型の別名なのかというと、それは処理系定義になります。

たとえばsize_t型であればsizeof演算子の評価結果の型なんですが、多くの32ビットCPUであれば符号付き32ビット整数で十分なのでunsigned int型になることが多いと思います。

64ビットCPUであれば符号付き64ビット整数が必要になります。
符号付き64ビット整数はWindowsであればunsigned long long型、LinuxやmacOSなどはunsigned long型に定義されます。
それ以外のプラットフォームでも適切な型に定義されています。

typedef

Cでは型の別名を付けるには「typedef指定子」を使います。
typedef指定子は規格上は「記憶クラス指定子」の一種になります。

記憶クラス指定子にはほかにstatic指定子やextern指定子があります。
static指定子はこれまでにも出てきましたね。
extern指定子についてはstatic指定子といっしょに別の機会にあらためて解説します。

typedef指定子は記憶クラス指定子といっても記憶とは何の関係もありません。
文法上たまたま記憶クラス指定子に分類されるというだけなので、あまり深く考えない方がいいと思います。

typedef指定子を使って別名を付けるには次のようにします。

typdef int integer;    // int型にintegerという別名を付ける
typedef int *pointer;  // int*というポインタ型にpointerという別名を付ける
typedef int array[10]; // int[10]という配列型にarrayと別名を付ける
typedef int (*array_pointer)[10]); // int(*)[10]という配列へのポインタ型にarray_pointerという別名を付ける
typedef int (*function)(int);      // int(*)(int)という関数へのポインタ型にfunctionという別名を付ける

上の例をご覧いただければ大体イメージできるのではないでしょうか?

typedef指定子で別名を付ければ複雑な型を簡単に表記することができます。
たとえば次のようにです。

int (*function_pointer_array[10])(int);       // int(int)型の関数へのポインタ型の10要素の配列

typedef int (*function_ponter)(int);          // int(int)型の関数へのポインタ型
function_pointer function_pointer_array2[10]; // functon_pointer型の10要素の配列

あえて複雑な型のオブジェクトを2つ宣言してみました。
1行目のfunction_pointer_arrayはtypedef指定子を使わずに直接オブジェクトを宣言しました。
一方、4行目のfunction_pointer_array2は、typedef指定子を使ってfunction_ponter型を定義した上で、それを使ってオブジェクトを宣言しています。

今後もtypedef名を出てくることはよくあると思いますので、「何だったかな?」となったときはこの記事に戻ってきてくださいね。

それでは今回の解説は以上となります。
割付け記憶域期間についての解説は多分週末になると思いますので、次回もこんな感じで短めの記事にするか、コラムなどを書くかもしれません。
あらかじめご了承ください。