Respostas:
Não.
#define
é um token de pré-processador: o próprio compilador nunca o verá.
typedef
é um token de compilador: o pré-processador não se importa com isso.
Você pode usar um ou outro para obter o mesmo efeito, mas é melhor usar o adequado para suas necessidades
#define MY_TYPE int
typedef int My_Type;
Quando as coisas ficam "peludas", o uso da ferramenta adequada acerta
#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);
; a declaração correta é void fx_def(void (*fx)(int));
.
#define FX_TYPE(f) void (*f)(int)
. Você declararia sua função como:void fx_def(FX_TYPE(fx));
typedef
obedece a regras de escopo como variáveis, enquanto define
permanece válido até o final da unidade de compilação (ou até uma correspondência undef
).
Além disso, algumas coisas podem ser feitas com as typedef
quais não podem ser feitas define
.
Por exemplo:
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
Não, eles não são os mesmos. Por exemplo:
#define INTPTR int*
...
INTPTR a, b;
Após o pré-processamento, essa linha se expande para
int* a, b;
Espero que você veja o problema; somente a
terá o tipo int *
; b
será declarado simples int
(porque *
está associado ao declarador, não ao especificador de tipo).
Compare isso com
typedef int *INTPTR;
...
INTPTR a, b;
Nesse caso, ambos a
e b
terão tipo int *
.
Existem classes inteiras de typedefs que não podem ser emuladas com uma macro de pré-processador, como ponteiros para funções ou matrizes:
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
Tente fazer isso com uma macro de pré-processador.
#define define macros.
typedef define tipos.
Agora dizendo isso, aqui estão algumas diferenças:
Com #define, você pode definir constantes que podem ser usadas em tempo de compilação. As constantes podem ser usadas com #ifdef para verificar como o código é compilado e especializar determinado código de acordo com os parâmetros de compilação.
Você também pode usar #define para declarar as funções macro de localização e substituição em miniatura .
O typedef pode ser usado para fornecer aliases aos tipos (o que você provavelmente também poderia fazer com #define ), mas é mais seguro devido à natureza de localização e substituição das constantes #define .
Além disso, você pode usar a declaração de encaminhamento com typedef, que permite declarar um tipo que será usado, mas ainda não está vinculado ao arquivo em que você está escrevendo.
As macros de pré-processador (" #define
s") são uma ferramenta de substituição lexical à "pesquisa e substituição". Eles são totalmente independentes da linguagem de programação e não entendem o que você está tentando fazer. Você pode pensar neles como um mecânico glorificado de copiar / colar - ocasionalmente isso é útil, mas você deve usá-lo com cuidado.
Typedefs são um recurso de linguagem C que permite criar aliases para tipos. Isso é extremamente útil para tornar tipos compostos complicados (como estruturas e ponteiros de função) legíveis e manipuláveis (em C ++, existem situações em que você deve digitar um tipo).
Para (3): você sempre deve preferir os recursos de idioma às macros do pré-processador quando isso for possível! Portanto, sempre use typedefs para tipos e valores constantes para constantes. Dessa forma, o compilador pode realmente interagir com você de forma significativa. Lembre-se de que o compilador é seu amigo, portanto, você deve contar o máximo possível. As macros de pré-processador fazem exatamente o contrário, ocultando sua semântica do compilador.
Eles são muito diferentes, embora sejam frequentemente usados para implementar tipos de dados personalizados (que é o que eu estou supondo que essa questão seja).
Como o pmg mencionado, #define
é tratado pelo pré-processador (como uma operação de recortar e colar) antes que o compilador veja o código e typedef
seja interpretado pelo compilador.
Uma das principais diferenças (pelo menos quando se trata de definir tipos de dados) é que typedef
permite uma verificação de tipo mais específica. Por exemplo,
#define defType int
typedef int tdType
defType x;
tdType y;
Aqui, o compilador vê a variável x como um int, mas a variável y como um tipo de dados chamado 'tdType' que passa a ter o mesmo tamanho que um int. Se você escreveu uma função que assumiu um parâmetro do tipo defType, o chamador poderia passar um int normal e o compilador não saberia a diferença. Se a função assumisse um parâmetro do tipo tdType, o compilador garantiria que uma variável do tipo apropriado fosse usada durante as chamadas de função.
Além disso, alguns depuradores têm a capacidade de lidar com typedef
s, o que pode ser muito mais útil do que ter todos os tipos personalizados listados como seus tipos primitivos subjacentes (como seria se #define
fosse usado em vez disso).
Não.
Typedef é uma palavra-chave C que cria um alias para um tipo.
#define é uma instrução de pré-processador, que cria um evento de substituição de texto antes da compilação. Quando o compilador chega ao código, a palavra original "#defined" não está mais lá. #define é usado principalmente para macros e constantes globais.
AFAIK, No.
typedef
ajuda a configurar um "alias" para um tipo de dados existente. Por exemplo. typedef char chr
;
#define
é uma diretiva de pré - processador usada para definir macros ou substituições gerais de padrão. Por exemplo. #define MAX 100
, substitui todas as ocorrências de MAX
com 100
Como mencionado acima, há uma diferença importante entre #define
e typedef. A maneira correta de pensar sobre isso é visualizar um typedef como sendo um tipo "encapsulado" completo. Isso significa que você não pode adicioná-lo depois de o ter declarado.
Você pode estender um nome de tipo de macro com outros especificadores de tipo, mas não um nome de tipo digitado:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Além disso, um nome digitado fornece o tipo para cada declarador em uma declaração.
#define fruit int *
fruit apple, banana;
Após a expansão da macro, a segunda linha se torna:
int *apple, banana;
A Apple é um ponteiro para um int, enquanto banana é um int. Em comparação. um typedef como este:
typedef char *fruit;
fruit apple, banana;
declara maçã e banana iguais. O nome na frente é diferente, mas ambos são ponteiros para um caractere.
Como todos disseram acima, eles não são os mesmos. A maioria das respostas indica typedef
ser mais vantajosa que #define
. Mas deixe-me colocar um ponto positivo de #define
:
quando seu código é extremamente grande, espalhado por muitos arquivos, é melhor usá-lo #define
; ajuda na legibilidade - você pode simplesmente pré-processar todo o código para ver a definição de tipo real de uma variável no local da própria declaração.
stdfx
, objetos válidos desse tipo são ponteiros para funções que recebem um int e não retornam um valor.