Para mayor comodidad sintáctica, typedef
se trata como un especificador de clase de almacenamiento, como extern
, static
o register
. Semánticamente, por supuesto, es bastante diferente, pero cuando se agregó typedef
al idioma, era más simple usar una parte de la gramática existente para definir su sintaxis.
Adición static
a una declaración de objeto no cambia el significado de la declaración excepto que cambia de clase de almacenamiento del objeto a "estática" (si no lo estaba ya):
{
int foo; /* automatic storage duration */
static int bar; /* static storage duration */
}
Sustitución static
con typedef
cambia el significado de la declaración, por lo que el nombre que se define no es un nombre de objeto, sino un nombre de tipo (en realidad sólo un alias para un tipo existente):
typedef int baz; /* "baz" is an alias for "int" */
La misma sintaxis se aplica a las declaraciones más complejas:
int (*a)[42]; /* a is a pointer to an array of 42 ints */
static int (*b)[42]; /* Same as a, but with static storage duration */
typedef int (*c)[42] /* c is an alias for the type int(*)[42], or
"pointer to array of 42 ints" */
Una vez que se dan cuenta que typedef
fue empujado de manera arbitraria en la misma ranura en la gramática ocupado por extern
, static
y register
, la comprensión de typedef
declaraciones no es más difícil (y sin ¡más fácil!) que entender declaraciones de objetos. (El programa de cdecl
y web site son útiles para el desembalaje declaraciones complejas.)
Usted también puede tener un typedef
para un tipo de función:
void func(void); /* declare func as a function */
typedef void func_type(void); /* declare func_type as a name
for a function type */
no se puede utilizar un tipo de función typedef
ed para declarar o definir una función, pero se puede utilizar para declarar una función de puntero:
func_type *ptr = func;
en cuanto a alcance (es decir, la región del programa de t extensión sobre la cual un identificador declarado es visible), un identificador definido por una declaración typedef
tiene el mismo alcance que cualquier otro identificador declarado. Si se declara en el alcance del archivo, fuera de cualquier función, es visible desde el punto de declaración hasta el final del archivo. Si se declara dentro de una función, es visible desde el punto en el que se declara hasta el final del bloque circundante más cercano. Y como cualquier declaración, puede ser ocultada por otra declaración con el mismo nombre en un ámbito interno.
también puede investigar 'typedef typename' construir – Anycorn
"Así que hay reglas" - nah, solo inventamos la sintaxis a medida que avanzamos. Los compiladores luego leen nuestras mentes para ver a qué nos referimos. –
@aaa: constructo 'typedef typename'? 'typename' se usa en plantillas para desambiguar tipos. Sería parte de un tipo; no es una forma especial de 'typedef'. –