より複雑な宣言の解釈

「複雑な宣言の特定の解釈方法を指定するには宣言子をかっこで囲むことができます」。複雑な宣言は複数の配列ポインターまたは関数の修飾子で修飾された識別子です。単一の識別子に配列ポインター関数の修飾子のさまざまな組み合わせを適用できます。通常 typedef 宣言が単純化するために使用される場合があります。typedef 宣言 を参照してください。

複雑な宣言の解釈で角かっこかっこ (つまり識別子の右側の修飾子) はアスタリスク (つまり識別子の左側の修飾子) より優先されます。角かっことかっこと同じ優先順位は左から右に関連付けます。宣言が完全に解釈されると型指定子は最後のステップとして適用されます。かっこを使用して既定の関連付けの順序をオーバーライドして特定の解釈ができます。ただし識別子名を囲むかっこは単独では使用しないでください。つまりパラメーター リストとして解釈できます。

複雑な宣言を解釈するための簡単な方法は4 種類の手順を使用してを 「」完全に読み取ることです :

  1. 角かっこまたはかっこの下に識別子および外観の開始直接 (存在する場合)。

  2. これらの角かっこかを解釈し左方向をアスタリスクを確認します。

  3. すべての段階で右かっこが発生した場合は戻りかっこ内のすべての規則 1 および 2 を適用します。

  4. 型指定子を適用します。

    char *( *(*var)() )[10];
     ^   ^  ^ ^ ^   ^    ^
     7   6  4 2 1   3    5
    

この例では順序で次のように番号を表示解釈できます。:

  1. 識別子 var はとして宣言されます

  2. へのポインター

  3. 関数を返します。

  4. へのポインター

  5. ある 10 個の要素の配列。

  6. へのポインター

  7. char の値。

次の例は他の複雑な宣言を記述しかっこが宣言の意味にどのように影響する方法を示します。

int *var[5]; /* Array of pointers to int values */

配列の修飾子にポインターの修飾子高優先順位があるためvar は配列として宣言されます。ポインターの修飾子は配列要素の型に適用します ; したがって配列要素は int の値へのポインターです。

int (*var)[5]; /* Pointer to array of int values */

この var の宣言ではかっこは配列の修飾子高優先順位ポインターの修飾子を使用 var は int の値 5 の配列へのポインターとして宣言されます。

long *var( long, long ); /* Function returning pointer to long */

関数の修飾子にポインターの修飾子高優先順位があるためvar の宣言はこの long の値へのポインターを返す関数に var を宣言します。関数は引数として long の 2 個の値を受け入れるように宣言されています。

long (*var)( long, long ); /* Pointer to function returning long */

この例では前の例に似ています。かっこは関数の修飾子高優先順位ポインターの修飾子を使用 var は long の値を返す関数へのポインターとして宣言されます。したがって関数は 2 long の二つの引数を受け取ります。

struct both       /* Array of pointers to functions */
{                 /*   returning structures         */
    int a;
    char b;
} ( *var[5] )( struct both, struct both );

配列の要素は関数にすることはできませんが関数へのポインターの配列を宣言する方法を次の例に示します。この例ではvar2 人のメンバーを持つ構造体を返す関数への 5 回のポインターの配列として宣言されます。関数の引数が同じ構造体の型である2 種類の構造both として宣言されます。*var[5] をかっこが必要であることに注意してください。それらがないと宣言は次に示すように関数を宣言する無効な操作です :

/* ILLEGAL */
struct both *var[5]( struct both, struct both );

次のステートメントはポインターの配列を宣言します。

unsigned int *(* const *name[5][10] ) ( void );

name の配列と多次元配列で構成される 50 個の要素があります。要素は定数のポインターへのポインターです。このパラメーターはなく符号なしの型へのポインターを返す関数への定数ポインターのポインター。

次の例 倍精度浮動小数点型 の値 3 の配列へのポインターを返す関数です。

double ( *var( double (*)[3] ) )[3];

この宣言では配列を返す関数が無効であるため配列へのポインターが返されます。ここでは var 倍精度浮動小数点型 の値 3 の配列へのポインターを返す関数として宣言されます。関数は var 1 個の引数を受け取ります。引数は戻り値など 倍精度浮動小数点型 の値 3 の配列へのポインターです。引数の型は複雑な 抽象宣言 で指定します。引数の型のアスタリスクを囲むかっこが必要です ; それらがない場合引数の型は 倍精度浮動小数点型 の値スリーポイントへの三つのポインターの配列です。抽象宣言の説明と例については抽象宣言 を参照してください。

union sign         /* Array of arrays of pointers */
{                  /* to pointers to unions       */
     int x;
     unsigned y;
} **var[5][5];

上の例に示すように別のポインターを指す配列が要素として配列を含めることができます。ここで var5 個の要素の配列です。各要素は2 人のメンバーを含む共用体へのポインターへのポインターの 5 要素の配列です。

union sign *(*var[5])[5]; /* Array of pointers to arrays
                             of pointers to unions        */

かっこの配置が宣言の意味がどのように変化するかを次の例に示します。この例ではvar は共用体へのポインターの 5 要素の配列へのポインターの 5 要素の配列です。typedef が複雑な宣言を回避する方法の例については typedef 宣言 を参照してください。

参照

概念

宣言と型