Sdílet prostřednictvím


Výklad složitějších deklarací

Libovolný deklarátor můžete uzavřít do závorek a určit konkrétní interpretaci "komplexního deklarátoru". Komplexní deklarátor je identifikátor kvalifikovaný více než jedním modifikátorem pole, ukazatelem nebo funkcí. U jednoho identifikátoru můžete použít různé kombinace modifikátorů pole, ukazatele a funkce. typedef Obecně lze použít ke zjednodušení deklarací. Viz Deklarace Typedef.

Při interpretaci složitých deklarátorů mají přednost hranaté závorky a závorky (tj. modifikátory napravo od identifikátoru) před hvězdičkami (tj. modifikátory vlevo od identifikátoru). Závorky a závorky mají stejnou prioritu a přidružit je zleva doprava. Po úplném interpretování deklarátoru se specifikátor typu použije jako poslední krok. Pomocí závorek můžete přepsat výchozí pořadí přidružení a vynutit konkrétní interpretaci. Nikdy však nepoužívejte závorky kolem názvu identifikátoru samostatně. Může se to chybně interpretovat jako seznam parametrů.

Jednoduchým způsobem, jak interpretovat složité deklarátory, je číst je "z vnitřní části", a to pomocí následujících čtyř kroků:

  1. Začněte identifikátorem a hledejte přímo napravo hranaté závorky nebo závorky (pokud existuje).

  2. Interpretujte tyto závorky nebo závorky a pak nalevo vyhledejte hvězdičky.

  3. Pokud narazíte na pravou závorku v libovolné fázi, vraťte se a použijte pravidla 1 a 2 pro všechno v závorkách.

  4. Použijte specifikátor typu.

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

V tomto příkladu jsou kroky očíslovány v pořadí a lze je interpretovat takto:

  1. var Identifikátor je deklarován jako

  2. ukazatel na

  3. vrácení funkce

  4. ukazatel na

  5. pole s 10 prvky, které jsou

  6. ukazatele na

  7. char hodnoty.

Příklady

Následující příklady ilustrují další složité deklarace a ukazují, jak mohou závorky ovlivnit význam deklarace.

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

Modifikátor pole má vyšší prioritu než modifikátor ukazatele, takže var je deklarován jako pole. Modifikátor ukazatele se vztahuje na typ prvků pole; proto jsou prvky pole ukazateli na int hodnoty.

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

V této deklaraci pro varzávorky poskytují modifikátor ukazatele vyšší prioritu než modifikátor pole a var je deklarován jako ukazatel na matici pěti int hodnot.

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

Modifikátory funkcí mají také vyšší prioritu než modifikátory ukazatele, takže tato deklarace deklarací var var je funkce vracející ukazatel na long hodnotu. Funkce je deklarována tak, aby jako argumenty převzala dvě long hodnoty.

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

Tento příklad je podobný předchozímu. Závorky dávají modifikátoru ukazatele vyšší prioritu než modifikátor funkce a var je deklarován jako ukazatel na funkci, která vrací long hodnotu. Funkce opět přebírá dva long argumenty.

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

Prvky pole nemohou být funkcemi, ale tato deklarace ukazuje, jak deklarovat pole ukazatelů na funkce. V tomto příkladu je deklarován jako matice pěti ukazatelů na funkce, var které vracejí struktury se dvěma členy. Argumenty funkcí jsou deklarovány jako dvě struktury se stejným typem struktury . both Všimněte si, že jsou vyžadovány závorky kolem *var[5] . Bez nich je deklarace neplatným pokusem o deklaraci pole funkcí, jak je znázorněno níže:

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

Následující příkaz deklaruje pole ukazatelů.

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

Pole name má 50 prvků uspořádaných do multidimenzionálního pole. Prvky jsou ukazatele na ukazatel, který je konstantní. Tento konstantní ukazatel odkazuje na funkci, která nemá žádné parametry a vrací ukazatel na nepodepsaný typ.

Tento další příklad je funkce vracející ukazatel na pole tří double hodnot.

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

V této deklaraci vrátí funkce ukazatel na matici, protože funkce vracející matice jsou neplatné. Zde var je deklarováno, že se jedná o funkci vracející ukazatel na pole tří double hodnot. Funkce var přebírá jeden argument. Argument, podobně jako návratová hodnota, je ukazatel na pole se třemi double hodnotami. Typ argumentu je dán komplexním abstraktním deklarátorem. Závorky kolem hvězdičky v typu argumentu jsou povinné; bez nich by typ argumentu byl polem tří ukazatelů na double hodnoty. Diskuzi a příklady abstraktních deklarátorů najdete v tématu Abstraktní deklarátory.

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

Jak ukazuje výše uvedený příklad, ukazatel může odkazovat na jiný ukazatel a pole může obsahovat pole jako prvky. Tady var je pole pěti prvků. Každý prvek je pole pěti prvků ukazatelů na ukazatele na sjednocení se dvěma členy.

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

Tento příklad ukazuje, jak umístění závorek změní význam deklarace. V tomto příkladu var je pole ukazatelů na pět prvků ukazatelů na pole ukazatelů na sjednocení. Příklady použití typedef , jak se vyhnout složitým deklaracím, najdete v tématu Deklarace Typedef.

Viz také

Deklarace a typy