tyedefの使い方
2076 ワード
プログラミングでtypedefを使用する目的は一般的に2つあり、1つは変数に覚えやすく意味の明確な新しい名前を与えることであり、もう1つは比較的複雑なタイプ宣言を簡略化することである.たとえば、81文字の要素の配列を次のように繰り返し定義する必要はありません.
char*const cp:文字を指すポインタ定数、すなわちconstポインタ、定数ポインタを定義します.
const char*p:文字型定数を指すポインタを定義します.
char const*p:const char*pと同等です.上記のtypedef動作は、同義語の代わりに実際のタイプのdefineマクロに似ています.異なる点はtypedefがコンパイル時に解釈されるため、コンパイラにプリプロセッサの能力を超えたテキスト置換に対処させることである.例:typedef int(*PF)(const char*,const char*);この宣言は、2つのconst char*タイプのパラメータとintタイプの戻り値を持つ関数ポインタの同義語としてPFタイプを導入した.次の形式の関数宣言を使用する場合、このtypedefは、PF Register(PF pf)であるか、または欠けているかのいずれかである.Register()のパラメータはPFタイプのコールバック関数であり,以前登録した名前と同じ署名を持つ関数のアドレスを返す.深呼吸をする.typedefを使わなければ、私たちはどのようにこの声明を実現したのかを示します.
typedefとストレージクラスキーワード(storage class specifier)
この言い方は少し驚いたのではないでしょうか.typedefはauto、extern、mutable、static、registerのように、ストレージクラスのキーワードです.これはtypedefがオブジェクトのストレージ特性に本当に影響するというわけではありません.文の構成上、typedef宣言はstatic、externなどの変数宣言のように見えます.2番目のトラップに移動します.
typedef register int FAST_COUNTER;//エラー
コンパイルは通じない.問題は、宣言に複数のストレージクラスキーワードが存在しないことです.シンボルtypedefがクラスキーワードを格納する場所を占めているため、typedef宣言ではregister(または他のクラスキーワードを格納する)は使用できません.
参考資料:http://baike.baidu.com/link?url=fDMjKVG-vR4U27jWQvQKzZ3JszMK0cdWaF4309Y8tFNxEazA5NwFdLoTsqq2CO1YRa7KZgfH9FQ6Tw2f2cu31K
char line[81];
char text[81];
このように定義するだけで、Lineタイプは81の要素を持つ文字配列を表し、次のように使用します.4 typedef char Line[81];
Line text,line;
getline(text);
同様に、ポインタ構文は次のように非表示にできます. typedef char* pstr;
int mystrcmp(const pstr p1,const pstr p3);
GNUのgccとg++コンパイラでは、「const pstr」は順番に「char*const」(charを指すポインタ定数)と解釈されるが、実際にはconst char*とchar*constは同じ意味ではない(詳細はC++Primer第4版P 112参照).char*const cp:文字を指すポインタ定数、すなわちconstポインタ、定数ポインタを定義します.
const char*p:文字型定数を指すポインタを定義します.
char const*p:const char*pと同等です.上記のtypedef動作は、同義語の代わりに実際のタイプのdefineマクロに似ています.異なる点はtypedefがコンパイル時に解釈されるため、コンパイラにプリプロセッサの能力を超えたテキスト置換に対処させることである.例:typedef int(*PF)(const char*,const char*);この宣言は、2つのconst char*タイプのパラメータとintタイプの戻り値を持つ関数ポインタの同義語としてPFタイプを導入した.次の形式の関数宣言を使用する場合、このtypedefは、PF Register(PF pf)であるか、または欠けているかのいずれかである.Register()のパラメータはPFタイプのコールバック関数であり,以前登録した名前と同じ署名を持つ関数のアドレスを返す.深呼吸をする.typedefを使わなければ、私たちはどのようにこの声明を実現したのかを示します.
int (*Register (int (*pf)(const char *, const char *)))
(const char *, const char *);
このような難解なコードがもたらすエラーのリスクは言うまでもありません.明らかに、ここでtypedefを使用するのは特権ではなく、必須です.疑念を抱いている人は「OK、こんなコードを書く人はいますか?」と聞くかもしれませんが、signal()関数を明らかにしたヘッダファイル、同じインタフェースを持つ関数をすばやく見てみましょう.ここでRegisterは、関数ポインタではなく関数ポインタとして定義されていることに注意してください.関数ポインタとして定義する場合は、int(*(*(*(*Register)(int(*pf)(const char*,const char*))(const char*,const char*);typedefとストレージクラスキーワード(storage class specifier)
この言い方は少し驚いたのではないでしょうか.typedefはauto、extern、mutable、static、registerのように、ストレージクラスのキーワードです.これはtypedefがオブジェクトのストレージ特性に本当に影響するというわけではありません.文の構成上、typedef宣言はstatic、externなどの変数宣言のように見えます.2番目のトラップに移動します.
typedef register int FAST_COUNTER;//エラー
コンパイルは通じない.問題は、宣言に複数のストレージクラスキーワードが存在しないことです.シンボルtypedefがクラスキーワードを格納する場所を占めているため、typedef宣言ではregister(または他のクラスキーワードを格納する)は使用できません.
参考資料:http://baike.baidu.com/link?url=fDMjKVG-vR4U27jWQvQKzZ3JszMK0cdWaF4309Y8tFNxEazA5NwFdLoTsqq2CO1YRa7KZgfH9FQ6Tw2f2cu31K