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ů:
Začněte identifikátorem a hledejte přímo napravo hranaté závorky nebo závorky (pokud existuje).
Interpretujte tyto závorky nebo závorky a pak nalevo vyhledejte hvězdičky.
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.
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:
var
Identifikátor je deklarován jakoukazatel na
vrácení funkce
ukazatel na
pole s 10 prvky, které jsou
ukazatele na
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 var
zá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.