C言語 | 構造体の宣言 | 型の別名 - typedef
typedef 指定子は、既存の型に別名を定義する。別名を使うと、コードを簡潔にし、移植性を高め、複雑な構造体やポインターの宣言を隠蔽できる。
型の別名
次の構文を使う。
typedef 既存の型 新しい型名;
たとえば、次のように記述する。
typedef unsigned char BYTE;
これで BYTE は unsigned char の別名になる。特定サイズの型が必要なプログラムでは、プラットフォーム固有のヘッダーで WORD や DWORD などの別名を適切な組み込み型へ割り当てると、移植性を高められる。
コード1
#include <stdio.h>
typedef unsigned char BYTE;
typedef int DWORD;
struct Color { BYTE r , g , b; };
DWORD main() {
struct Color color = { 0xFF , 0xAA , 0xAA };
printf("R = %d : G = %d : B = %d\n" , color.r , color.g , color.b);
return 0;
}
別名を定義しても、異なる実体型が作られるわけではない。BYTE と DWORD は通常のC言語の型に対する別名である。
ポインター型にも別名を付けられる。
typedef char STR , *PSTR;
これは STR を char、PSTR を char * の別名として定義する。
コード2
#include <stdio.h>
typedef char STR , *PSTR;
int main() {
STR str[] = "Kitty on your lap";
PSTR pstr = str;
printf("%s\n" , pstr);
return 0;
}
構造体の別名
構造体では struct キーワードを繰り返さずに済むため、別名が特に便利である。
struct tag_Point { int x , y; };
typedef struct tag_Point Point;
後で構造体タグを使わない場合は、無名構造体と別名を同時に定義できる。
typedef struct { int x , y; } Point;
コード3
#include <stdio.h>
typedef struct { int x , y; } Point;
int main() {
Point po = { 200 , 50 };
printf("X = %d : Y = %d\n" , po.x , po.y);
return 0;
}
共用体にも同じ方法を利用できる。
関数型と別名
関数にも、戻り値の型と引数リストで決まる型がある。同じシグネチャを持つ独立した関数は、同じ関数型である。
関数型へ別名を付けるには、次の構文を使う。
typedef 戻り値型 新しい型名(引数リスト);
コード4
#include <stdio.h>
typedef void TEXTOUT(char *str);
TEXTOUT println;
int main() {
println("Kitty on your lap");
return 0;
}
void println(char *str) {
printf("%s\n" , str);
}
TEXTOUT println; は void println(char *str); の宣言と同等である。