Sdílet prostřednictvím


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

Všechny deklarátory lze uzavřít do závorek pro určení konkrétního výkladu "komplexního deklarátoru." Komplexní deklarátor je identifikátor kvalifikován více než jedním polem, ukazatelem nebo modifikátorem funkce.Na jeden identifikátor lze použít různé kombinace polí, ukazatelů a modifikátorů funkcí.Obecně lze typedef použít pro zjednodušení deklarace.Více informací naleznete v tématu Deklarace typedef.

Při výkladu složitých deklarátorů mají jednoduché a složené závorky (tj. modifikátory napravo od identifikátoru) přednost před hvězdami (tj. modifikátory nalevo od identifikátoru).A složené a jednoduché závorky mají stejnou prioritu a asociace pro ně platí zleva doprava.Po tom, co byl deklarátor plně interpretován, je jako poslední krok použit specifikátor typu.Pomocí závorek lze přepsat výchozí pořadí přidružení a vynutit určitou interpretaci.Závorky se nesmí používat okolo samotného názvu identifikátoru.Mohlo by tím dojít k záměně za seznam parametrů.

Jednoduchý způsob, jak interpretovat komplexní deklarátory je načtením "zevnitř ven," pomocí následujících čtyř kroků:

  1. Nejdříve je třeba začít s identifikátorem a vpravo vyhledat jednoduché nebo složené závorky (pokud existují).

  2. Interpretovat tyto jednoduché nebo složené závorky a následně je třeba vlevo vyhledat hvězdičky.

  3. Jsou-li napravo nalezeny závorky, je třeba jít zpět a aplikovat pravidla 1 nebo 2 na vše, co se nachází uvnitř závorek.

  4. Použití specifikátoru typu.

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

Kroky v tomto příkladu jsou číslovány podle pořadí a lze je interpretovat následujícím způsobem:

  1. Identifikátor var je deklarován jako

  2. ukazatel na

  3. funkci vracející

  4. ukazatel na

  5. pole 10 prvků, které jsou

  6. ukazateli na

  7. hodnoty char.

Příklady

Následující příklad ukazuje další složité deklarace a ukazuje, jakým způsobem mohou závorky ovlivnit smysl deklarace.

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

Modifikátor pole má vyšší prioritu než modifikátor ukazatele, var je tedy deklarován jako pole.Modifikátor ukazatele se vztahuje na prvky pole. Prvky pole jsou tedy ukazateli na hodnoty int.

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

V deklaraci var dávají závorky modifikátoru ukazatele vyšší prioritu než modifikátoru pole a var je deklarován jako ukazatel na pole pěti hodnot int.

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

Modifikátory funkce mají také vyšší prioritu než modifikátory ukazatele, a proto deklarace var deklaruje var jako funkci vracející ukazatel na hodnotu long.Funkce je deklarována pro převzetí dvou hodnot long jako argumenty.

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átoru funkce a var je deklarován jako ukazatel na funkci, která vrací hodnotu long.Funkce opět přebírá dva argumenty typu long.

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

Prvky pole nemohou být funkce, ale tato deklarace místo toho ukazuje, jak deklarovat pole ukazatelů funkce.V tomto příkladu je var deklarován jako pole pěti ukazatelů na funkce, které vracejí struktury se dvěma členy.Argumenty funkcí jsou deklarovány jako dvě struktury stejného typu struktury both.Všimněte si, že závorky kolem *var[5] jsou povinné.Bez nich by deklarace představovala neplatný pokus o deklaraci pole funkcí, jak je ukázá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 vícerozměrného pole.Prvky jsou ukazatele na ukazatel, který je konstanta.Ukazatel na konstantu odkazuje na funkci, která nemá žádné parametry a vrací ukazatel na nepodepsaný typ.

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

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

V této deklaraci vrací funkce ukazatel na pole, jelikož funkce vracející pole jsou neplatné.Zde je var deklarován jako funkce, která vrací ukazatel na pole tří hodnot typu double.Funkce var přebírá jeden argument.Argument jako je návratová hodnota, je ukazatel na pole tří hodnot typu double.Typ argumentu je dán komplexním abstraktním deklarátorem.Závorky kolem hvězdičky jsou v typu argumentu požadovány. Bez nich by byl typ argumentu pole tří ukazatelů na hodnoty typu double.Diskuse a příklady abstraktních deklarátorů lze nalézt 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 je vidět na výše uvedeném příkladu, ukazatel může odkazovat na jiný ukazatel a pole může obsahovat pole jako prvky.Zde je var pole pěti prvků.Každý prvek je pole o velikosti 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 změní umístění závorek smysl deklarace.V tomto příkladu je var pole o pěti prvcích ukazatelů na pole o pěti prvcích ukazatelů na sjednocení.Příklady použití typedef pro zabránění komplexních deklarací naleznete v tématu Deklarace typedef.

Viz také

Koncepty

Deklarace a typy