Cuatro usos y dos trampas de typedef en lenguaje C
para definir un alias que no sea simplemente un simple reemplazo de macro. Se puede utilizar para declarar varios objetos de tipos de puntero al mismo tiempo. Por ejemplo:
char* pa, Pb; // La mayor parte de esto no está en línea con nuestra intención original. Simplemente declara un puntero a una variable de carácter.
//Y una variable de carácter;
Lo siguiente es factible:
typedef char * PCHAR//Generalmente use letras mayúsculas.
PCHAR pa, Pb; // factible, declara dos punteros a variables de caracteres.
Aunque:
char *pa, *pb
también es factible, pero es relativamente menos intuitivo que typedef, especialmente cuando hay una gran cantidad de punteros. requerido, typedef Más conveniente.
Uso 2:
Se utiliza para construcciones auxiliares en código C antiguo. En el código anterior, al declarar un nuevo objeto de estructura, se debe traer estructura, es decir, en la forma: estructura nombre de estructura nombre de objeto, como por ejemplo:
Marca de estructura punto 1
{
int x;
int y;
};
estructura marcar punto 1 p 1;
En C++, puedes escribir directamente: nombre de la estructura nombre del objeto, es decir:
punto de etiqueta 1 p 1;
Supongo que algunas personas piensan que escribir un estructura adicional a menudo, por lo que inventaron:
punto de marca de estructura typedef
{
int x
int y
}point;
Haga clic en p 1; // Esto ahorra escribir una estructura que el método original, lo cual es más conveniente, especialmente cuando se usa en grandes cantidades.
Quizás, en C++, typedef no sea muy útil, pero aún así es útil entenderlo para dominar el código antiguo. Después de todo, es posible que nos encontremos con código sobrante de los primeros días del proyecto.
Uso 3:
Utilice typedef para definir tipos independientes de la plataforma.
Por ejemplo, defina un tipo de punto flotante llamado REAL para que represente el tipo 1 de mayor precisión en la plataforma de destino:
typedef long double real;
En la segunda plataforma que no admite doble largo, cámbielo a:
typedef double real;
En la tercera plataforma que ni siquiera admite doble, cámbielo a:
typedef float REAL
En otras palabras, cuando se trata de multiplataforma, solo necesita cambiar el typedef en sí y no necesita realizar ningún cambio en otra fuente. códigos.
Esta técnica es muy utilizada en bibliotecas estándar, como size_t.
Además, typedef es más robusto que la macro porque define un alias para un nuevo tipo en lugar de un simple reemplazo de cadena (aunque a veces la macro puede lograr el propósito anterior).
Uso 4:
Defina nuevos alias simples para declaraciones complejas. El método es: reemplazar gradualmente algunas declaraciones complejas con alias en la declaración original, y así sucesivamente, dejando la parte con nombres de variables hasta el final para reemplazarla, para obtener la versión más simplificada de la declaración original.
Por ejemplo:
1. Declaración original: int *(A[5])(int, char *);
La variable se llama a, así que use el nuevo alias pFun. Reemplazar a:
typedef int * *(pFun)(int, char *);
Versión más simple de la declaración original:
pFun a[5] ;
2. Declaración original: void(* b[10])(void(*));
El nombre de la variable es b, primero reemplace el que está en el corchete derecho, pFunParam es el alias 1:
typedef void(* pfun param)();
Reemplaza las variables b a la izquierda, b, pFunx es el alias 2:
typedef void (* pFunx)(pfun param);
La versión más simple de la declaración original:
pFunx b[10];
3. declaración: doube( *)(* e)[9];
El nombre de la variable es e, reemplace la parte izquierda primero, pFuny es el alias 1:
typedef double(* pFuny )();
p>Reemplace la variable e a la derecha, e, pFunParamy es el alias dos.
typedef pFuny(* pFunParamy)[9];
La versión más simple de la declaración original:
pFunParamy e;
Comprender la complejidad Las "reglas de izquierda y derecha" disponibles para las declaraciones: a partir del nombre de la variable, primero gire a la derecha, luego a la izquierda y gire hacia la dirección de lectura cuando encuentre un paréntesis para saltar fuera del paréntesis después de analizar el paréntesis, o presione hacia la derecha; primero y luego a la izquierda, y así sucesivamente hasta completar la frase del análisis. Por ejemplo:
int(* func)(int * p);
Primero busque el nombre de la variable func. Hay un par de corchetes afuera y un * a la izquierda, lo que indica. esa func es un puntero; luego salte los paréntesis, primero mire el lado derecho y luego encuentre los paréntesis, lo que indica que (* func) es una función, por lo que func es un puntero a este tipo de función, es decir, una función. puntero. Esta función tiene parámetros de tipo int* y el tipo de valor de retorno es int.
int(* func[5])(int *);
El lado derecho de func es el operador [], lo que significa que func es una matriz con 5 elementos; El lado izquierdo de func es Un signo * indica que el elemento de func es un puntero (tenga en cuenta que el signo * aquí no es un modificador de func, sino un modificador de func[5], porque el operador [] tiene una prioridad más alta que el signo * y func se combina con la combinación [] primero). Salte de este corchete, mire a la derecha y encuentre paréntesis, lo que indica que los elementos de la matriz func son punteros de tipo de función. La función a la que apunta tiene un parámetro de tipo int* y el tipo de valor de retorno es int.
También puedes recordar dos modos:
Tipo(*)() puntero de función
Tipo(*)[]puntero de matriz
Trampa 1:
Recuerde, un typedef es un nuevo alias para un tipo definido. A diferencia de las macros, no se trata de una simple sustitución de cadenas. Por ejemplo:
Primero defina:
typedef char * PSTR;
Luego:
int mystrcmp(PSTR constante, PSTR constante) ;
¿Es const PSTR realmente equivalente a const char*? No, en realidad es equivalente a char* const.
La razón es que const le da constancia a todo el puntero, es decir, se forma el puntero const char* const.
En pocas palabras, recuerde que cuando const y typedef aparecen juntos, typedef no será un simple reemplazo de cadena.
Trampa 2:
Typedef es sintácticamente una palabra clave para clases de almacenamiento (como auto, extern, mutable, static, Register, etc.).
), aunque realmente no afecta las características de almacenamiento del objeto, por ejemplo:
typedef static int INT2 // no es factible
La compilación fallará y le preguntará "Almacenamiento múltiple tipo especificado".