Compartir a través de


Información general sobre los declaradores

Los declaradores son los componentes de una declaración que especifican nombres de objetos o funciones. Los declaradores también especifican si el objeto con nombre es o no un objeto, puntero, referencia o matriz. Aunque los declaradores no especifican el tipo base, modifican la información de tipo del tipo básico para especificar tipos derivados, como punteros, referencias y matrices. Cuando se aplica a las funciones, el declarador funciona con el especificador de tipo para especificar completamente que el tipo de valor devuelto de una función es un objeto, puntero o referencia. (Los especificadores, que se describen en Declaraciones, transmiten propiedades tales como el tipo y la clase de almacenamiento. Los modificadores, que se describen en esta sección y en Modificadores específicos de Microsoft, modifican los declaradores). En la ilustración siguiente se muestra una declaración completa de MyFunction y se llama a los componentes de la declaración.

Especificadores, modificadores y declaradores

Modificadores, especificadores y declaradores

Específicos de Microsoft

La mayoría de las palabras clave extendidas de Microsoft se pueden utilizar como modificadores para formar tipos derivados; no son especificadores ni declaradores. (Vea Modificadores específicos de Microsoft).

FIN de Específicos de Microsoft

Los declaradores aparecen en la sintaxis de declaración después de una lista opcional de especificadores. Estos especificadores se describen en Declaraciones. Una declaración puede contener varios declaradores, pero cada declarador declara un solo nombre.

En la declaración de ejemplo siguiente se muestra cómo se combinan especificadores y declaradores para formar una declaración completa:

const char *pch, ch;

En la declaración anterior, las palabras clave const y char forman parte de la lista de especificadores. La lista contiene dos declaradores: *pch y ch. Una declaración que declara varias entidades está formada por un especificador de tipo seguido de una lista separada por comas de declaradores, finalizada con un punto y coma.

Declaradores de objetos simples

El declarador de un objeto simple, como int o double, es simplemente su nombre, con paréntesis opcionales.

int i; // declarator is i

int (i); // declarator is (i)

Declaradores de punteros, referencias y matrices

Los operadores de puntero que se insertan delante del nombre hacen que el objeto sea un puntero o referencia. El operador * declara el nombre como puntero; el operador & lo declara como referencia.

int *i; // declarator is *i
int **i; // declarator is **i;
int &i = x; // declaratory is &i

Al anexar const o volatile, se proporcionan al puntero estas propiedades especiales. El uso de estos especificadores en un declarador (frente al especificador de tipo) modifica las propiedades del puntero, no el objeto al que se señala:

char *const cpc; // const pointer to char 
const char *pcc; // pointer to const char 
const char *const cpcc; // const pointer to const char

Encontrará información adicional en Punteros const y volatile.

Un puntero a un miembro de una clase o struct se declara con el especificador de nombre anidado adecuado:

int X::* pIntMember; 
int ::X::* pIntMember; // the initial :: specifies X is in global scope
char Outer::Inner::* pIntMember; // pointer to char in a nested class

Los corchetes que rodean una expresión constante opcional después del nombre hacen que el objeto sea una matriz. Los corchetes posteriores declaran dimensiones adicionales de la matriz.

int i[5]; // array with five elements of type int numbered from 0 to 4
int i[]; // array of unknown size
char *s[4]; // array of pointers to char
int i[2][2]; // two dimensional array

Declaradores de funciones

Se usan paréntesis alrededor de la lista de argumentos, detrás del nombre, para declarar una función. A continuación, se declara una función del tipo de valor devuelto int y tres argumentos de tipo int.

int f(int a, int b, int c);

Para obtener información sobre las listas de argumentos, vea Declaraciones de función.

Los punteros y referencias a funciones se declaran mediante la anteposición del puntero u operador de referencia al nombre de función, como se muestra a continuación. Se requieren paréntesis, normalmente opcionales, para distinguir un puntero a una función de una función que devuelve un puntero:

int (*pf)(int); // pointer to function returning int
int *f(int i); // function returning pointer to int
int (&pf)(int); // reference to function 

Los punteros a funciones miembro se distinguen por los especificadores de nombre anidados:

int (X::* pmf)(); // pointer to member function of X returning int
int* (X::* pmf)(); // pointer to member function returning pointer to int

Vea también Punteros a miembros.

Funciones y objetos en la misma declaración

Las funciones y objetos se pueden declarar en la misma declaración, como se indica a continuación:

int i, *j, f(int k);  // int, pointer to int, function returning int

La sintaxis puede ser confusa en algunas circunstancias. La siguiente declaración

int* i, f(int k);  // pointer to int, function returning int (not int*)

puede parecer la declaración de un puntero int y una función que devuelve int*, pero no lo es. Esto se debe a que * es parte del declarador de i, no parte del declarador de f.

Simplificación de la sintaxis del declarador con typedef

Sin embargo, existe una técnica mejor, que consiste en utilizar typedef o una combinación de paréntesis y la palabra clave typedef. Considere, por ejemplo, una matriz de punteros a funciones:

//  Function returning type int that takes one 
//   argument of type char *.
typedef int (*PIFN)( char * );
//  Declare an array of 7 pointers to functions 
//   returning int and taking one argument of type 
//   char *.
PIFN pifnDispatchArray[7];

La declaración equivalente se puede escribir sin la declaración de typedef, pero es tan complicado que las posibilidades de error superan cualquier ventaja:

int ( *pifnDispatchArray[7] )( char * );

Para obtener más información sobre typedef, vea el especificador typedef.

Los punteros, referencias y matrices de un solo tipo base se pueden combinar en una sola declaración (separados por comas), como

int a, *b, c[5], **d, &e=a;

Una sintaxis de declarador más compleja

  • Los declaradores de punteros, referencias, matrices y funciones se pueden combinar para especificar objetos tales como matrices de punteros a funciones, punteros a matrices, etc.

  • La gramática recursiva siguiente describe la sintaxis completa de un declarador de puntero.

  • declarator se define como:

1. identifier 
2. qualified-name 
3. declarator ( argument-list ) [cv-qualfiers] [exception-spec]
4. declarator [ [ constant-expression ] ] 

5. pointer-operator declarator 
6. ( declarator )
  • y pointer-operator es:
* [cv-qualifiers]
& [cv-qualifiers]
:: nested-name-specifier * [cv-qualfiers]

Dado que un declarador puede contener declaradores, es posible construir los tipos derivados más complejos, como matrices de punteros, funciones que devuelven matrices de punteros a función, mediante las reglas anteriores. Para formar cada paso de la construcción, comience con el identificador que representa el tipo de datos base y aplique la regla de sintaxis anterior con la expresión anterior como declarator. El orden de aplicación de las reglas de sintaxis debe ser el inverso de como se indica la expresión en inglés. Si se aplica la regla de sintaxis de pointer-operator en una expresión de matriz o función, utilice paréntesis si desea un puntero a la matriz o función, como en la última fila de la tabla siguiente.

En el ejemplo siguiente, se muestra la construcción de “puntero a matriz de 10 punteros a int”.

Expresión verbal

Declarador

Regla de sintaxis aplicada

i

1

puntero(s) a

*i

5

matriz de 10

(*i)[10]

4

puntero a

*((*i)[10])

6 y después 5

Cuando se utilizan varios modificadores de puntero, referencia, matriz o función, los declaradores pueden resultar bastante complicados. En el tema Interpretación de los declaradores más complejos se describe cómo leer una sintaxis de declarador más compleja. El tema es aplicable a C y C++, aunque en C++, en cualquier lugar donde se use * para indicar un puntero, se puede usar un nombre calificado tal como MyClass::* para especificar un puntero a un miembro de una clase.

Vea también

Referencia

Declaradores