Red de conocimientos sobre prescripción popular - Remedios caseros - ¿Para qué se utiliza la herramienta Typedef en C++ y cómo utilizarla? ¿Alguien puede presentarla?

¿Para qué se utiliza la herramienta Typedef en C++ y cómo utilizarla? ¿Alguien puede presentarla?

Resumen del uso de typedef:

Cuando miré el programa en los últimos dos días, descubrí que typedef se usa ampliamente en muchos lugares, como definiciones de estructuras y algunas matrices. Pero algunas partes no están muy claras, así que quiero estudiarlas esta tarde. Busqué en internet y encontré mucha información. En resumen:

Código fuente 1: utilice typedefs para suprimir códigos de error

Las declaraciones de Typedef ayudan a crear tipos independientes de la plataforma e incluso ocultan sintaxis complejas y difíciles de entender. En cualquier caso, utilizar typedef puede aportar beneficios inesperados al código. Con este artículo, podrá aprender a utilizar typedefs para evitar defectos y hacer que su código sea más sólido.

Una declaración Typedef, o typedef para abreviar, crea un nuevo nombre para un tipo existente. Por ejemplo, la gente suele utilizar typedefs para escribir código más bonito y legible. La llamada belleza es que typedef puede ocultar estructuras de sintaxis torpes y tipos de datos dependientes de la plataforma, mejorando así la portabilidad y la mantenibilidad futura. Este artículo intentará revelar el poder de los typedefs y cómo evitar algunos errores comunes.

¿Cómo crear tipos de datos independientes de la plataforma que oculten una sintaxis torpe e incomprensible?

Utilice typedefs para crear sinónimos para tipos existentes.

Defina un nombre de tipo que sea fácil de recordar.

Typedef se utiliza más comúnmente para crear nombres de tipos fáciles de recordar que documentan la intención del programador. El tipo aparece en el nombre de la variable declarada, a la derecha de la palabra clave "typedef". Por ejemplo:

typedef int size

Esta declaración define un sinónimo de tamaño llamado int. Tenga en cuenta que typedef no crea nuevos tipos. Simplemente agrega un sinónimo a un tipo existente. Puede usar tamaño en cualquier contexto donde se espera un int:

null Measure(size * psz

size array[4]; = file .getlength();

STD::vector vs;

Typedef también puede enmascarar tipos coincidentes, como punteros y matrices. Por ejemplo, no es necesario definir repetidamente una matriz con elementos de 81 caracteres como esta:

char fila[81]

char text[81];

Defina un typedef siempre que desee utilizar una matriz del mismo tipo y tamaño, puede hacer esto:

línea de caracteres typedef[81];

línea de texto, segunda line ;

getline(text);

De manera similar, la sintaxis del puntero se puede ocultar de la siguiente manera:

typedef char * pstr

int mystrcmp( pstr, pstr);

Esto nos lleva a la primera trampa de typedef. La función estándar strcmp() tiene dos parámetros de tipo "constchar *". Por lo tanto, puede resultar engañoso declarar mystrcmp() como:

int mystrcmp(const pstr, const pstr);

Esto es incorrecto. Por cierto, "constpstr" se interpreta como "char * const" (puntero constante a char), no como "const char *" (puntero a char constante). Este problema se resuelve fácilmente:

typedef const char * cpstr

int mystrcmp(cpstr, cpstr); // Ahora correcto.

Recuerde: siempre que declare un typedef para un puntero, debe agregar una constante al nombre final del typedef para que el puntero en sí sea una constante, no un objeto.

Simplificación de código

El Typedef discutido anteriormente se comporta como una macro #define, reemplazando un sinónimo con su tipo real. La diferencia es que los typedefs se interpretan en tiempo de compilación, por lo que el compilador puede manejar sustituciones textuales más allá de las capacidades del preprocesador. Por ejemplo:

typedef int (*PF) (const char *, const char *);

Esta declaración introduce el tipo PF como sinónimo de puntero de función, que tiene dos const Parámetros de tipo char * y un valor de retorno de tipo int. Este typedef es esencial si desea utilizar la siguiente forma de declaración de función:

Registro PF (PF PF);

El parámetro de Register() es una función de devolución de llamada de tipo PF , devuelve la dirección de una función con la misma firma que el nombre registrado previamente. Respira hondo. Permítanme mostrarles cómo implementamos esta declaración sin typedef:

int(* Register(int(* pf)(const char *, const char *))

(const char *, const char *);

Pocos programadores entienden lo que esto significa, y mucho menos el riesgo de errores que plantea un código tan incomprensible. Obviamente, aquí el uso de typedefs no es un privilegio, es un requisito. , "Bueno, ¿alguien escribiría un código como este?". Un vistazo rápido al archivo de encabezado muestra la función signal(), que tiene la misma interfaz p>

Typedef y especificadores de clase de almacenamiento

. ¿No es esto un poco sorprendente? typedef es una palabra clave de clase de almacenamiento, similar a auto, extern, mutable, static y Register. Significa que typedef realmente afectará las características de almacenamiento del objeto, solo significa eso en términos de estructura de oración. , las declaraciones de typedef parecen declaraciones de variables estáticas, externas y de otro tipo. Lo siguiente conducirá a la segunda trampa:

typedef.Registrar int FAST _ COUNTER // Error

Error de compilación. El problema es que no puede haber más de una palabra clave de clase de almacenamiento en la declaración. No se puede utilizar Register (o cualquier otra palabra clave de clase de almacenamiento) en una declaración de typedef. El símbolo typedef ha tomado el lugar de las palabras clave de clase de almacenamiento.

Promover el desarrollo multiplataforma

Typedef tiene otro propósito importante, que es definir tipos independientes de la máquina. Por ejemplo, puede definir un tipo de punto flotante llamado REAL que alcance la mayor precisión. la máquina de destino:

typedef long double real;

En máquinas que no admiten long double, typedef se vería así:

typedef double real;

Además, en una máquina que ni siquiera admite doble, el typedef se vería así:

typedef float REAL

Puedes compilar esta aplicación en cualquier plataforma con tipos reales sin realizar ningún cambio en el código fuente. La mayoría de las veces, incluso este es el propio typedef. También se pueden implementar pequeños cambios automáticamente a través de la maravillosa compilación condicional, ¿no es así? biblioteca estándar para crear tipos independientes de la plataforma: size_t, ptrdiff y fpos_t son ejemplos. Además, std::string, std:: Typedefs como ofstream también ocultan una sintaxis de especialización de plantilla larga y difícil de entender, como: basic_string, allocator. > y basic_ofstream >.

Acerca del autor

Danny Kalev es un analista de sistemas certificado e ingeniero de software especializado en C++ y teoría del lenguaje formal. De 1997 a 2000 fue miembro del Comité de Estándares de C++.

Recientemente completó su tesis de maestría en lingüística general con honores. En su tiempo libre le gusta escuchar música clásica, leer literatura victoriana y aprender idiomas naturales como el hitita, el vasco y el gaélico irlandés. Otros intereses incluyen la arqueología y la geografía. Danny suele asistir a algunos foros de C++ y escribe artículos regularmente para diferentes sitios web y revistas de C++. También imparte clases de lenguajes de programación y lenguajes aplicados en instituciones educativas.

Fuente 2: (/bbs/dispbbs.asp?boardid = 30 & id=4455)

Uso de typedef en lenguaje C

1.

Typedef es una palabra clave en lenguaje C, utilizada para definir un nuevo nombre para un tipo de datos. Los tipos de datos aquí incluyen tipos de datos internos (int, char, etc.) y tipos de datos definidos por el usuario (struct, etc.).

Typedef se usa generalmente para dos propósitos en la programación. Uno es proporcionar. variables con Elija un nuevo nombre que sea fácil de recordar y que tenga un significado claro. En segundo lugar, simplifique algunas declaraciones de tipos complejos.

En cuanto a las sutilezas de typedef, consulte las explicaciones detalladas de varias preguntas.

2.Problema de estructura de typedef y amp

Al utilizar el siguiente código para definir la estructura, el compilador informó un error. ¿Por qué? ¿C no permite un puntero a sí mismo en una estructura? Primero adivine y luego lea las siguientes instrucciones:

estructura typedef marca nodo

{

char * pItem

pNode pNext

} * pNode

Respuesta y análisis:

El uso más simple de 1 y typedef

typedef long byte_ 4;

Asigne al tipo de datos conocido un nuevo nombre, llamado byte_4.

2. Typedef combinado con estructura.

typedef struct tagMyStruct

{

int iNum

longitud larga;

} MyStruct

Esta declaración en realidad completa dos operaciones:

1) Define un nuevo tipo de estructura.

Estructura estructura de etiquetas

{

int iNum

Longitud larga;

};

Análisis: tagMyStruct se llama "etiqueta", es decir, "etiqueta", que en realidad es un nombre temporal. La palabra clave struct y tagMyStruct juntas forman este tipo de estructura. Esta estructura existe independientemente de si existe un typedef o no.

Podemos usar struct tagMyStruct varName para definir variables, pero es incorrecto usar la etiqueta MyStruct Varname para definir variables, porque la estructura y la etiqueta MyStruct pueden representar un tipo de estructura juntas.

2) Typedef le dio un nombre a esta nueva estructura, llamada MyStruct.

typedef struct tagmy struct my struct;

Entonces MyStruct es en realidad equivalente a struct tagMyStruct, y podemos usar MyStruct varName para definir variables.

Respuesta y análisis

Por supuesto, el lenguaje C permite que las estructuras contengan punteros a sí mismas. Podemos ver innumerables ejemplos de esto en la implementación de estructuras de datos como listas enlazadas. El problema fundamental con el código anterior es la aplicación de typedef.

De acuerdo con lo que explicamos anteriormente, podemos saber que la declaración del campo pNext se encuentra en el proceso de establecer una nueva estructura y el tipo es pNode. Debe saber que pNode representa el nuevo nombre del tipo, por lo que antes de crear el tipo en sí, el nuevo nombre de este tipo no existe, lo que significa que el compilador no conoce pNode en absoluto en este momento.

Hay muchas formas de resolver este problema:

1),

nodo de marca de estructura typedef

{

char * pItem

struct tagNode * pNext

} * pNode

2),

typedef struct tagNode * pNode

Nodo de etiqueta de estructura

{

char * pItem

pNode pNext

};

Nota: En este ejemplo, usa typedef para darle un nuevo nombre a un tipo que no está completamente declarado. El compilador del lenguaje C admite este enfoque.

3). Enfoque estándar:

Nodo de etiqueta de estructura

{

char * pItem

estructura tagNode. * pNext

};

typedef struct tagNode * pNode

3.typedef & amp#definition problema

Hay dos formas de hazlo Define el tipo de datos pStr. ¿Cuál es la diferencia entre los dos? ¿Cuál es mejor?

typedef char * pStr

#define pStr char *;

Respuesta y análisis:

En términos generales, typedef es mejor que # Defina Bueno, especialmente con punteros. Mire este ejemplo:

typedef char * pstr 1;

#define pstr 2 char *;

pStr1 s1, S2;

pStr2 s3, S4;

En la definición de variable anterior, s1, s2, s3 están definidos como char * y s4 está definido como char, que no es la variable de puntero que esperábamos. La causa principal es que #define es solo un simple reemplazo de cadena, mientras que typedef le da un nuevo nombre a un tipo.

Ejemplo de uso de #define:

#define f(x) x*x

main( )

{

int a=6, b=2, c;

c = f(a)/f(b);

printf("%d \\n ", c);

}

La salida del siguiente programa es: 36.

Por esta razón, en muchas especificaciones de programación en lenguaje C, cuando se usa la definición #define, si la definición contiene expresiones y se deben usar paréntesis, la definición anterior debe definirse de la siguiente manera:

#Define f(x) (x*x)

Por supuesto, si usas typedef, este problema no existe.

4.Otro ejemplo de typedef & amp#define

El compilador informará un error en el siguiente código. ¿Sabes qué afirmación está mal?

typedef char * pStr

char string[4]= "ABC";

const char * p 1 = string;

const pStr p2 = string

p 1++;

p2++;

Respuesta y análisis:

P2++ está mal. Esta pregunta nos recuerda nuevamente que typedef se diferencia de #define en que no es un simple reemplazo de texto. Constpsttrp2 en el código anterior no es igual a const char * p2. Básicamente, no hay diferencia entre const pStr p2 y const long x. Ambas son restricciones de solo lectura para las variables. Sin embargo, el tipo de datos de la variable p2 aquí lo definimos nosotros mismos, no el tipo inherente del sistema.

Entonces const pStr p2 significa que la variable p2 con tipo de datos char* está calificada como de solo lectura, por lo que p2++ es incorrecta.

Acerca de la expansión de #define y typedef

1) La definición de macro #define tiene una ventaja especial: puedes usar #ifdef, #ifndef, etc. Para hacer juicios lógicos, también puedes usar #undef para cancelar la definición.

2) Typedef también tiene una ventaja especial: cumple con las reglas de alcance. El alcance del tipo de variable definido por typedef se limita a la función o archivo definido (dependiendo de la ubicación de la definición de la variable). , mientras macro La definición no tiene esta propiedad.

5.typedef & amp declaración de variables complejas

En la práctica de programación, especialmente al leer el código de otras personas, a menudo nos encontramos con declaraciones de variables complejas. La simplificación usando typedefs tiene su propio valor, por ejemplo:

La siguiente es la declaración de tres variables. Quiero usar typdef para definir alias para ellos respectivamente. ¿Qué debo hacer?

& gt1:int *(*a[5])(int, char *);

& gt2:void(* b[10])(void(*)) ;

& gt3.doube(*)(* * pa)[9];

Respuesta y análisis:

Cómo crear alias de tipo para variables complejas Muy sencillo. Solo necesita reemplazar el nombre de la variable en la expresión de declaración de variable tradicional con el nombre del tipo y luego agregar la palabra clave typedef al comienzo de la declaración.

& gt1:int *(*a[5])(int, char *);

//pFun es el alias de tipo que creamos.

typedef int * *(pFun)(int, char *);

//Declarar un objeto con un nuevo tipo definido, equivalente a int *(a[5]) ( int, char *);

pFun a[5];

& gt2:void(* b[10])(void(*));

//Primero declare un nuevo tipo para la parte azul de la expresión anterior.

typedef void(* pfun param)();

//Declarar un nuevo tipo como un todo.

typedef void(* pFun)(pFun param);

//Declara un objeto con un nuevo tipo definido, equivalente a void(* b[10])(void(* ));

pFun b[10];

& gt3.doube(*)(* * pa)[9];

//El primero es La parte azul de la expresión anterior declara un nuevo tipo.

typedef double(* pFun)();

//Declarar un nuevo tipo como un todo.

typedef pFun(* pFun param)[9];

//Declara un objeto con un nuevo tipo definido, equivalente a doube(*)(* pa)[9] ;

pFunParam