typedef 宣言
提供: cppreference.com
typedef 宣言は識別子を型エイリアスとして宣言する方法を提供します。 複雑になり得る型名を置換するために使用されます。
キーワード typedef は、文法的には、宣言の記憶域クラス指定子の位置で使用されます。 ただし、記憶域やリンケージには影響を与えません。
typedefint int_t;// int のエイリアスとして int_t を宣言します。typedefchar char_t, *char_p, (*fp)(void);// char のエイリアスとして char_t を、// char* のエイリアスとして char_p を、// char(*)(void) のエイリアスとして fp を宣言します。
目次 |
[編集]説明
宣言で記憶域クラス指定子として typedef が使用された場合、その宣言内のすべての宣言子は、識別子を指定された型のエイリアスとして定義します。 ひとつの宣言では記憶域クラス指定子はひとつしか使用できないため、 typedef 宣言は static や extern にはできません。
typedef 宣言は新しい型は導入しません。 既存の型に対する同義語を確立するだけです。 そのため typedef 名はそのエイリアス元の型と互換です。 typedef 名は、列挙子、変数、関数などの普通の識別子と名前空間を共有します。
VLA に対する typedef はブロックスコープでのみ使用できます。 配列の長さは、制御の流れがその typedef 宣言を通るとき (配列の宣言時ではなく) に、毎回評価されます。 void copyt(int n){typedefint B[n];// B は VLA であり、そのサイズはこの時点で評価された n の値です。 n +=1; B a;// a のサイズは +=1 する前の n です。int b[n];// a と b はサイズが異なります。for(int i =1; i < n; i++) a[i-1]= b[i];} | (C99以上) |
[編集]ノート
typedef 名は不完全型であることもあり、通常通り、完全化されることもあります。
typedefint A[];// A は int[] です。 A a ={1, 2}, b ={3,4,5};// a の型は int[2] で、 b の型は int[3] です。
typedef 宣言はタグ名前空間の名前を通常の名前空間に注入するためによく使用されます。
typedefstruct tnode tnode;// 通常の名前空間内の tnode は// タグ名前空間内の tnode へのエイリアスです。struct tnode {int count; tnode *left, *right;// struct tnode *left, *right; と同じです。};// ここで tnode も完全型になります。 tnode s, *sp;// struct tnode s, *sp; と同じです。
タグ名前空間の使用を完全に回避することもできます。
typedefstruct{double hi, lo;} range; range z, *zp;
typedef 名は複雑な構文の宣言を単純化するためにもよく使用されます。
// int 3個の配列へのポインタを返す関数へのポインタ5個の配列。int(*(*callbacks[5])(void))[3]; // typedef を使って同じことをしてみます。typedefint arr_t[3];// int 3個の配列...typedef arr_t* fun_t(void);// ...へのポインタを返す関数... fun_t* callbacks[5];// ...へのポインタ5個の配列。
ライブラリは、ユーザにまたは他のライブラリコンポーネントに一貫したインタフェースを提示するために、システム依存またはコンフィグレーション依存の型に typedef 名を使用することがよくあります。
#if defined(_LP64)typedefintwchar_t;#elsetypedeflongwchar_t;#endif