「typedef」を使うと,既存の型に別の型名を付けることができる.
「typedef」を使って定義された型名は,既存の型と全く同じように使うことができる.
typedef 型の定義 新型名;
(例) typedef double real; ← 新しい型の定義 real f(real x); ← 関数のプロトタイプ宣言 real a, b, c, d[100], *p1; ← 変数宣言 real f(real x) ← 関数の定義 { retrun x*x; }
既存の型に対してtypedefを使うのは特別な目的の場合だけだろう.
typedef は,構造体に対して使うことが多い.これによって,structという 「内部事情」を隠してしまって,プログラムの「意味」を浮き立たせることができ, 「読みやすさ」「書きやすさ」が向上する.
struct タグ名 { 型名1 メンバ名1; 型名2 メンバ名2; ...; }; typedef struct タグ名 型名;
(例) struct complexTag { double re; double im; }; typedef struct complexTag complex;
タグ名と型名は同じ名前でも良い.
タグ名を省略して, テンプレートの宣言と型名の定義を一緒に書くこともできる. これは,便利なのでよく使う.
typedef struct { 型名1 メンバ名1; 型名2 メンバ名2; ...; } 型名;
(例) typedef struct { double re; double im; } complex;
このように定義された型名は,既存の型と全く同じように使うことができる.
(例) complex f(complex x); ← 関数のプロトタイプ宣言 complex a, b, c, d[100], *p1; ← 変数宣言 complex f(complex x) ← 関数の定義 { complex y; y.re = x.re*x.re - x.im*x.im; y.im = 2*x.re*x.im; return y; }
ただし,後述する自己参照構造体では,タグ名を省略できない.
typedef struct { ←構造体と型名の定義 int n; /* 分子 (numerator) */ int d; /* 分母 (denominator) */ } fraction; (中略) int main(void) { fraction x1, x2, x3; x1 = fracMake(3, 4); ← 代入 x2 = fracMake(5, -6); ← 代入 printf("x1 = "); fracPrint(x1); printf("\n"); ← 表示 printf("x2 = "); fracPrint(x2); printf("\n"); ← 表示 x3 = fracAdd(x1, x2); ← 足し算 printf("x1 + x2 = "); fracPrint(x3); printf("\n"); ← 表示 x3 = fracMul(x1, x2); ← 掛け算 printf("x1 * x2 = "); fracPrint(x3); printf("\n"); ← 表示 x3 = fracAdd(fracMul(x1, x1), fracMul(x2, x2)); ← 混合計算 printf("x1*x1 + x2*x2 = "); fracPrint(x3); printf("\n"); ← 表示 } (後略)