ルールは何ですか? OTOH単純なケースは、新しいタイプが行の最後のものであることを暗示しているようです。ここのようにUchar
は新しいタイプです:
typedef unsigned char Uchar;
しかし、関数ポインタは完全に異なります。ここで、新しいタイプはpFunc
です。
typedef int (*pFunc)(int);
他の例をすぐに思いつくことはできませんが、非常に紛らわしい使用法に出くわしました。
それで、ルールはありますか、それとも人々はこれが以前にこのように行われたのを見たので、これがどのように行われるかを経験から知っているはずですか?
また:typedef
の範囲は何ですか?
基本的に、typedef
の構文はオブジェクト宣言とまったく同じですが、接頭辞としてtypedef
が付いており、新しい識別子がオブジェクトの型のエイリアスを宣言するように意味が変更されています。それが通常の宣言であったならば、宣言されていたでしょう。
typedef
は、オブジェクト宣言とまったく同じスコープであるため、ファイルスコープであるか、ブロックに対してローカルであるか、(C++では)名前空間またはクラスに対してローカルである可能性があります。
例えば.
int
を宣言します:
int a;
int
のエイリアスであるタイプを宣言します。
typedef int a_type;
char
へのポインタを宣言します:
char *p;
char *
のエイリアスを宣言します:
typedef char *pChar;
関数ポインタを宣言します:
int (*pFn)(int);
'int
を受け取りint
を返す関数へのポインタである型のエイリアスを宣言します。
typedef int (*pFunc)(int);
構文上の便宜のために、typedef
は、extern
、static
、またはregister
のように、ストレージクラス指定子として扱われます。意味的にはもちろんまったく異なりますが、typedef
が言語に追加されたときは、既存の文法を使用して構文を定義する方が簡単でした。
オブジェクト宣言にstatic
を追加しても、オブジェクトのストレージクラスが「静的」に変更される(そうでない場合)ことを除いて、宣言の意味は変更されません tすでに):
{
int foo; /* automatic storage duration */
static int bar; /* static storage duration */
}
static
をtypedef
に置き換えると、宣言の意味が変わり、定義される名前はオブジェクト名ではなくタイプ名(実際には既存のタイプの単なるエイリアス)になります。
typedef int baz; /* "baz" is an alias for "int" */
同じ構文がより複雑な宣言にも適用されます。
int (*a)[42]; /* a is a pointer to an array of 42 ints */
static int (*b)[42]; /* Same as a, but with static storage duration */
typedef int (*c)[42] /* c is an alias for the type int(*)[42], or
"pointer to array of 42 ints" */
typedef
がextern
、static
、およびregister
によって占められている文法の同じスロットに任意に押し込まれていることに気付いたら、typedef
宣言を理解することは、オブジェクト宣言を理解することよりも難しくありません(そして簡単ではありません!)。 (cdecl
プログラムと Webサイト は、複雑な宣言を解凍するのに役立ちます。)
関数タイプにtypedef
を設定することもできます。
void func(void); /* declare func as a function */
typedef void func_type(void); /* declare func_type as a name
for a function type */
typedef
ed関数タイプを使用して関数を宣言または定義することはできませんが、それを使用して関数ポインターを宣言することはできます。
func_type *ptr = func;
scope(宣言された識別子が表示されるプログラムテキストの領域を意味します)に関しては、typedef
宣言によって定義された識別子は他のものと同じスコープを持ちます他の宣言された識別子。関数の外部のファイルスコープで宣言されている場合は、宣言のポイントからファイルの終わりまで表示されます。関数内で宣言されている場合は、宣言されたポイントから最も近い囲んでいるブロックの終わりまで表示されます。また、他の宣言と同様に、内部スコープ内の同じ名前の別の宣言によって非表示にすることができます。
他の誰もそれについて言及しなかったという理由だけで:それは常に任意のオブジェクトビルドにローカライズされます。したがって、同じusing/typedef名で異なるcppファイルをコンパイルしている場合、それらは互いに影響しません。