Interpretando declaradores mais complexos

Você pode colocar qualquer Declarador entre parênteses para especificar uma determinada interpretação dos "Declarador complexo". Uma complexa Declarador é um identificador qualificado por mais de uma matriz, um ponteiro ou um modificador de função.Você pode aplicar várias combinações de modificadores de função, ponteiro e matriz a um único identificador.Geralmente, typedef pode ser usado para simplificar declarações.Consulte Typedef declarações.

Interpretar declaradores complexos, colchetes e parênteses (ou seja, modificadores para a direita do identificador) prevalecem sobre asteriscos (ou seja, modificadores para a esquerda do identificador).Colchetes e parênteses têm a mesma precedência e associar-se da esquerda para a direita.Depois que o Declarador foi totalmente interpretado, o especificador de tipo é aplicado como a última etapa.Usando parênteses, você pode substituir a ordem de associação padrão e forçar uma interpretação particular.Nunca use parênteses, no entanto, ao redor de um nome de identificador por si só.Isso poderia ser mal interpretado como uma lista de parâmetros.

Uma maneira simples de interpretar declaradores complexas é lê-las "de dentro para fora," usando as quatro etapas a seguintes:

  1. Inicie com o identificador e procure diretamente para a direita para colchetes ou parênteses (se houver).

  2. Interpretar esses colchetes ou parênteses e, em seguida, examinar para a esquerda para asteriscos.

  3. Se você encontrar um parêntese direito em qualquer estágio, volte e aplicar regras 1 e 2 para todos os itens dentro dos parênteses.

  4. Aplica o especificador de tipo.

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

Neste exemplo, as etapas são numeradas na ordem e podem ser interpretadas da seguinte forma:

  1. O identificador var é declarada como

  2. um ponteiro para

  3. uma função de retorno

  4. um ponteiro para

  5. uma matriz de elementos de 10, que são

  6. ponteiros para

  7. charvalores.

Exemplos

Os exemplos a seguir ilustram a outras declarações complexas e mostram como os parênteses podem afetar o significado de uma declaração.

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

O modificador de matriz tem prioridade mais alta que o modificador de ponteiro, então, var está declarada como uma matriz.O modificador de ponteiro aplica-se ao tipo dos elementos da matriz; Portanto, os elementos da matriz são ponteiros para int valores.

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

Nessa declaração para var, parênteses dar a ponteiro modificador maior prioridade em relação o modificador de matriz, e var está declarada como um ponteiro para uma matriz de cinco int valores.

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

Modificadores de função também têm prioridade mais alta que os modificadores de ponteiro, portanto, essa declaração de var declara var para ser uma função retornar um ponteiro para uma longo valor.A função é declarada para capturar duas longo valores como argumentos.

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

Este exemplo é semelhante ao anterior.Parênteses dar a ponteiro modificador maior prioridade em relação o modificador de função, e var está declarada como um ponteiro para uma função que retorna um longo valor.Novamente, a função leva dois longo argumentos.

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

Os elementos de uma matriz não podem ser funções, mas essa declaração demonstra como declarar uma matriz de ponteiros para funções em vez disso.Neste exemplo, var está declarada como uma matriz de cinco ponteiros para funções que retornam estruturas com dois membros.Os argumentos para as funções são declarados duas estruturas com o mesmo tipo de estrutura, both.Observe que os parênteses em torno do *var[5] são necessários.Sem eles, a declaração é uma tentativa ilegal de declarar uma matriz de funções, como mostrado abaixo:

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

A instrução a seguir declara uma matriz de ponteiros.

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

O name matriz tem 50 elementos organizados em uma matriz multidimensional.Os elementos são ponteiros para um ponteiro que é uma constante.Esse ponteiro constante aponta para uma função que não tem parâmetros e retorna um ponteiro para um tipo não assinado.

Este próximo exemplo é uma função retornar um ponteiro para uma matriz de três double valores.

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

Nessa declaração, uma função retorna um ponteiro para uma matriz, desde funções retornam matrizes são ilegais.Aqui var está declarada como uma função retornar um ponteiro para uma matriz de três double valores.A função var tem um argumento.O argumento, como o valor de retorno é um ponteiro para uma matriz de três double valores.O tipo de argumento é dado por um complexo de Declarador de resumo da.Os asterisco no tipo de argumento entre parênteses são necessários; sem eles, o tipo de argumento seria uma matriz de três ponteiros para double valores.Para uma discussão e exemplos de declaradores abstratas, consulte Abstrata declaradores.

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

Como mostra o exemplo acima, um ponteiro pode apontar para outro ponteiro e uma matriz pode conter matrizes como elementos.Aqui var é uma matriz de cinco elementos.Cada elemento é uma matriz de cinco elementos de ponteiros para ponteiros para uniões com dois membros.

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

Este exemplo mostra como o posicionamento de parênteses altera o significado da declaração.Neste exemplo, var é uma matriz de cinco elementos de ponteiros para o elemento de cinco conjuntos de ponteiros para uniões.Para obter exemplos de como usar o typedef para evitar declarações complexas, consulte Typedef declarações.

Consulte também

Conceitos

Declarações e tipos