Respuestas:
No.
#define
es un token de preprocesador: el compilador en sí nunca lo verá.
typedef
es un token compilador: al preprocesador no le importa.
Puede usar uno u otro para lograr el mismo efecto, pero es mejor usar el adecuado para sus necesidades
#define MY_TYPE int
typedef int My_Type;
Cuando las cosas se ponen "peludas", usar la herramienta adecuada lo hace correcto
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
void fx_def(void (*)(int) fx);
; La declaración correcta es void fx_def(void (*fx)(int));
.
#define FX_TYPE(f) void (*f)(int)
. Luego declararía su función como:void fx_def(FX_TYPE(fx));
typedef
obedece las reglas de alcance al igual que las variables, mientras que define
permanece válido hasta el final de la unidad de compilación (o hasta una coincidencia undef
).
Además, se pueden hacer algunas cosas con las typedef
que no se puede hacer define
.
Por ejemplo:
typedef int* int_p1;
int_p1 a, b, c; // a, b, c are all int pointers
#define int_p2 int*
int_p2 a, b, c; // only the first is a pointer, because int_p2
// is replaced with int*, producing: int* a, b, c
// which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c; // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp; // func_p is a pointer to a function that
// takes an int and returns an int
No, no son lo mismo. Por ejemplo:
#define INTPTR int*
...
INTPTR a, b;
Después del preprocesamiento, esa línea se expande a
int* a, b;
Espero que veas el problema; solo a
tendrá el tipo int *
; b
se declarará sin formato int
(porque *
está asociado con el declarador, no con el especificador de tipo).
Contrasta eso con
typedef int *INTPTR;
...
INTPTR a, b;
En este caso, tanto a
y b
tendrá tipo int *
.
Hay clases enteras de typedefs que no se pueden emular con una macro de preprocesador, como punteros a funciones o matrices:
typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20];
...
CALLBACK aCallbackFunc; // aCallbackFunc is a pointer to a function
// returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
// returning a pointer to a 20-element array
// of pointers to int
Intenta hacerlo con una macro de preprocesador.
#define define macros.
typedef define tipos.
Ahora diciendo eso, aquí hay algunas diferencias:
Con #define puedes definir constantes que se pueden usar en tiempo de compilación. Las constantes se pueden usar con #ifdef para verificar cómo se compila el código y especializar cierto código de acuerdo con los parámetros de compilación.
También puede usar #define para declarar funciones macro de buscar y reemplazar en miniatura .
typedef se puede usar para dar alias a los tipos (lo que probablemente también podría hacer con #define ), pero es más seguro debido a la naturaleza de búsqueda y reemplazo de #define constantes.
Además de eso, puede usar la declaración hacia adelante con typedef que le permite declarar un tipo que se usará, pero que aún no está vinculado al archivo en el que está escribiendo.
Las macros de preprocesador (" #define
's") son una herramienta de reemplazo léxico a la "búsqueda y reemplazo". Son completamente agnósticos del lenguaje de programación y no entienden lo que estás tratando de hacer. Puede pensar en ellos como una mecánica glorificada de copiar / pegar; en ocasiones es útil, pero debe usarla con cuidado.
Typedefs es una característica del lenguaje C que le permite crear alias para los tipos. Esto es extremadamente útil para hacer que los tipos compuestos complicados (como estructuras y punteros de función) sean legibles y manejables (en C ++ incluso hay situaciones en las que debe escribir typedef a type).
Para (3): ¡siempre debe preferir las características del lenguaje a las macros de preprocesador! Por lo tanto, use siempre typedefs para tipos y valores constantes para constantes. De esa manera, el compilador puede interactuar contigo significativamente. Recuerde que el compilador es su amigo, por lo que debe contarlo tanto como sea posible. Las macros de preprocesador hacen exactamente lo contrario al ocultar su semántica del compilador.
Son muy diferentes, aunque a menudo se usan para implementar tipos de datos personalizados (que es de lo que supongo que se trata esta pregunta).
Como se mencionó pmg, #define
el preprocesador lo maneja (como una operación de cortar y pegar) antes de que el compilador vea el código, y typedef
el compilador lo interpreta.
Una de las principales diferencias (al menos cuando se trata de definir tipos de datos) es que typedef
permite una verificación de tipos más específica. Por ejemplo,
#define defType int
typedef int tdType
defType x;
tdType y;
Aquí, el compilador ve la variable x como int, pero la variable y como un tipo de datos llamado 'tdType' que resulta ser del mismo tamaño que un int. Si escribió una función que tomara un parámetro de tipo defType, la persona que llama podría pasar un int normal y el compilador no notaría la diferencia. Si la función en su lugar tomó un parámetro de tipo tdType, el compilador se aseguraría de que se utilizara una variable del tipo adecuado durante las llamadas de función.
Además, algunos depuradores tienen la capacidad de manejar typedef
s, lo que puede ser mucho más útil que tener todos los tipos personalizados listados como sus tipos primitivos subyacentes (como lo sería si #define
se usara en su lugar).
No.
typedef es una palabra clave C que crea un alias para un tipo.
#define es una instrucción previa al procesador, que crea un evento de reemplazo de texto antes de la compilación. Cuando el compilador llega al código, la palabra original "#definida" ya no está allí. #define se usa principalmente para macros y constantes globales.
AFAIK, No.
typedef
le ayuda a configurar un "alias" para un tipo de datos existente. Por ej. typedef char chr
;
#define
es una directiva de preprocesador utilizada para definir macros o sustituciones de patrones generales. Por ej. #define MAX 100
, sustituye todas las apariciones de MAX
con 100
Como se mencionó anteriormente, hay una diferencia clave entre #define
y typedef. La forma correcta de pensar en eso es ver un typedef como un tipo "encapsulado" completo. Significa que no puede agregarlo después de haberlo declarado.
Puede ampliar un nombre de tipo de macro con otros especificadores de tipo, pero no un nombre de tipo definido por tipo:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Además, un nombre typedef'd proporciona el tipo para cada declarante en una declaración.
#define fruit int *
fruit apple, banana;
Después de la expansión macro, la segunda línea se convierte en:
int *apple, banana;
Apple es un puntero a un int, mientras que banana es un int. En comparación. un typedef como este:
typedef char *fruit;
fruit apple, banana;
declara que tanto la manzana como el plátano son iguales. El nombre en el frente es diferente, pero ambos son indicadores de un personaje.
Como todos dijeron anteriormente, no son lo mismo. La mayoría de las respuestas indican typedef
ser más ventajosas que #define
. Pero permítanme poner un punto positivo #define
:
cuando su código es extremadamente grande, disperso en muchos archivos, es mejor usarlo #define
; ayuda en la legibilidad: simplemente puede preprocesar todo el código para ver la definición de tipo real de una variable en el lugar de su declaración.
stdfx
, los objetos válidos de ese tipo son punteros a funciones que reciben un int y no devuelven un valor.