Interpretazione di più dichiaratori complessiInterpreting More Complex Declarators

È possibile racchiudere qualsiasi dichiaratore tra parentesi per specificare un'interpretazione particolare di un "dichiaratore complesso".You can enclose any declarator in parentheses to specify a particular interpretation of a "complex declarator." Un dichiaratore complesso è un identificatore qualificato da più matrici, puntatori o modificatori di funzione.A complex declarator is an identifier qualified by more than one array, pointer, or function modifier. È possibile applicare varie combinazioni di matrice, puntatore e modificatori di funzione a un singolo identificatore.You can apply various combinations of array, pointer, and function modifiers to a single identifier. typedef può essere utilizzato in genere per semplificare dichiarazioni.Generally typedef may be used to simplify declarations. Vedere Dichiarazioni typedef.See Typedef Declarations.

Nell'interpretazione dei dichiaratori complessi, le parentesi quadre e le parentesi (ovvero modificatori a destra dell'identificatore) hanno la precedenza sugli asterischi (ovvero modificatori a sinistra dell'identificatore).In interpreting complex declarators, brackets and parentheses (that is, modifiers to the right of the identifier) take precedence over asterisks (that is, modifiers to the left of the identifier). Parentesi quadre e parentesi tonde hanno la stessa precedenza e vengono associate da sinistra a destra.Brackets and parentheses have the same precedence and associate from left to right. Dopo che il dichiaratore è stato completamente interpretato, l'identificatore del tipo viene applicato come ultimo passaggio.After the declarator has been fully interpreted, the type specifier is applied as the last step. Utilizzando le parentesi tonde è possibile eseguire l'override dell'ordine di associazione predefinito e forzare un'interpretazione particolare.By using parentheses you can override the default association order and force a particular interpretation. Non utilizzare mai le parentesi, tuttavia, attorno al nome di un identificatore da solo.Never use parentheses, however, around an identifier name by itself. Ciò potrebbe essere interpretato erroneamente come un elenco di parametri.This could be misinterpreted as a parameter list.

Un modo semplice per interpretare i dichiaratori complessi consiste nel leggerli da "dall'interno verso l'esterno", utilizzando i quattro passaggi seguenti:A simple way to interpret complex declarators is to read them "from the inside out," using the following four steps:

  1. Iniziare con l'identificatore e individuare direttamente le eventuali parentesi quadre o le parentesi tonde presenti sulla destra.Start with the identifier and look directly to the right for brackets or parentheses (if any).

  2. Interpretare queste parentesi quadre o parentesi tonde, quindi individuare gli asterischi sulla sinistra.Interpret these brackets or parentheses, then look to the left for asterisks.

  3. Se durante una delle fasi si rileva una parentesi chiusa, tornare indietro e applicare le regole 1 e 2 a qualsiasi elemento all'interno delle parentesi.If you encounter a right parenthesis at any stage, go back and apply rules 1 and 2 to everything within the parentheses.

  4. Applicare l'identificatore di tipo.Apply the type specifier.

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

    In questo esempio, i passaggi sono numerati in ordine e possono essere interpretati come segue:In this example, the steps are numbered in order and can be interpreted as follows:

  5. L'identificatore var viene dichiarato comeThe identifier var is declared as

  6. un puntatore aa pointer to

  7. una funzione che restituiscea function returning

  8. un puntatore aa pointer to

  9. una matrice di 10 elementi, che sonoan array of 10 elements, which are

  10. puntatori apointers to

  11. valori char.char values.

EsempiExamples

Negli esempi seguenti vengono illustrate altre dichiarazioni complesse e mostrato come le parentesi possono influire sul significato di una dichiarazione.The following examples illustrate other complex declarations and show how parentheses can affect the meaning of a declaration.

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

Il modificatore di matrice ha priorità più alta rispetto al modificatore del puntatore, quindi var viene dichiarato come una matrice.The array modifier has higher priority than the pointer modifier, so var is declared to be an array. Il modificatore del puntatore viene applicato al tipo degli elementi di matrice; pertanto, gli elementi di matrice sono puntatori ai valori int.The pointer modifier applies to the type of the array elements; therefore, the array elements are pointers to int values.

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

In questa dichiarazione per var, mediante le parentesi viene associata al modificatore di puntatore una priorità più elevata rispetto al modificatore di matrice e var viene dichiarato come puntatore a una matrice di cinque valori int.In this declaration for var, parentheses give the pointer modifier higher priority than the array modifier, and var is declared to be a pointer to an array of five int values.

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

I modificatori di funzione dispongono anche di priorità più alta rispetto ai modificatori del puntatore, pertanto questa dichiarazione per var dichiara che var è una funzione che restituisce un puntatore a un valore long.Function modifiers also have higher priority than pointer modifiers, so this declaration for var declares var to be a function returning a pointer to a long value. La funzione viene dichiarata come in grado di accettare come argomenti due valori long.The function is declared to take two long values as arguments.

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

Questo esempio è simile al precedente.This example is similar to the previous one. Le parentesi assegnano priorità più elevata al modificatore del puntatore rispetto al modificatore di funzione e var viene dichiarato come puntatore a una funzione che restituisce un valore long.Parentheses give the pointer modifier higher priority than the function modifier, and var is declared to be a pointer to a function that returns a long value. Anche in questo caso la funzione accetta due argomenti long.Again, the function takes two long arguments.

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

Gli elementi di una matrice non possono essere funzioni, ma questa dichiarazione dimostra come dichiarare una matrice di puntatori a funzioni.The elements of an array cannot be functions, but this declaration demonstrates how to declare an array of pointers to functions instead. In questo esempio, var viene dichiarato come una matrice di cinque puntatori a funzioni che restituiscono strutture con due membri.In this example, var is declared to be an array of five pointers to functions that return structures with two members. Gli argomenti alle funzioni vengono dichiarati come due strutture con lo stesso tipo di struttura, both.The arguments to the functions are declared to be two structures with the same structure type, both. Si noti che le parentesi che racchiudono *var[5] sono necessarie.Note that the parentheses surrounding *var[5] are required. Senza di esse, la dichiarazione è un tentativo non valido di dichiarare una matrice di funzioni, come illustrato di seguito:Without them, the declaration is an illegal attempt to declare an array of functions, as shown below:

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

L'istruzione seguente dichiara una matrice di puntatori.The following statement declares an array of pointers.

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

La matrice name dispone di 50 elementi organizzati in una matrice multidimensionale.The name array has 50 elements organized in a multidimensional array. Gli elementi sono puntatori a un puntatore che è una costante.The elements are pointers to a pointer that is a constant. Questo puntatore constant fa riferimento a una funzione non ha alcun parametro e restituisce un puntatore a un tipo unsigned.This constant pointer points to a function that has no parameters and returns a pointer to an unsigned type.

L'esempio seguente è una funzione che restituisce un puntatore a una matrice di tre valori double.This next example is a function returning a pointer to an array of three double values.

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

In questa dichiarazione, una funzione restituisce un puntatore a una matrice, poiché le funzioni che restituiscono matrici non sono consentite.In this declaration, a function returns a pointer to an array, since functions returning arrays are illegal. In questo caso var è dichiarato come funzione che restituisce un puntatore a una matrice di tre valori double.Here var is declared to be a function returning a pointer to an array of three double values. La funzione var accetta un argomento.The function var takes one argument. L'argomento, come il valore restituito, è un puntatore a una matrice di tre valori double.The argument, like the return value, is a pointer to an array of three double values. Il tipo di argomento viene specificato da un abstract-declarator complesso.The argument type is given by a complex abstract-declarator. Le parentesi che racchiudono l'asterisco nel tipo di argomento sono necessarie; senza parentesi il tipo di argomento sarebbe una matrice di tre puntatori a valori double.The parentheses around the asterisk in the argument type are required; without them, the argument type would be an array of three pointers to double values. Per informazioni ed esempi di dichiaratori abstract, vedere Dichiaratori abstract.For a discussion and examples of abstract declarators, see Abstract Declarators.

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

Come illustrato nell'esempio precedente, un puntatore può indicare un altro puntatore e una matrice può contenere matrici come elementi.As the above example shows, a pointer can point to another pointer, and an array can contain arrays as elements. In questo caso var è una matrice di cinque elementi.Here var is an array of five elements. Ogni elemento è una matrice di cinque elementi di puntatori ai puntatori a unioni con due membri.Each element is a five-element array of pointers to pointers to unions with two members.

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

In questo esempio viene mostrato come la posizione delle parentesi modifica il significato della dichiarazione.This example shows how the placement of parentheses changes the meaning of the declaration. In questo esempio, var è una matrice di cinque elementi dei puntatori a matrici di cinque elementi dei puntatori a unioni.In this example, var is a five-element array of pointers to five-element arrays of pointers to unions. Per esempi dell'uso di typedef per evitare dichiarazioni complesse, vedere Dichiarazioni typedef.For examples of how to use typedef to avoid complex declarations, see Typedef Declarations.

Vedere ancheSee Also

Dichiarazioni e tipiDeclarations and Types