web-dev-qa-db-fra.com

Est-ce que typedef et #define sont identiques en c?

Je me demande si typedef et #define sont identiques dans c ?

106
hdn

Non.

#define est un jeton de préprocesseur: le compilateur lui-même ne le verra jamais.
typedef est un jeton de compilateur: le préprocesseur ne s'en soucie pas.

Vous pouvez utiliser l'un ou l'autre pour obtenir le même effet, mais il est préférable d'utiliser celui qui convient à vos besoins.

#define MY_TYPE int
typedef int My_Type;

Quand les choses deviennent "poilues", l'utilisation du bon outil le rend bien

#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);

void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
106
pmg

typedef obéit aux règles de délimitation tout comme les variables, alors que define reste valide jusqu'à la fin du fichier (ou jusqu'à une undef correspondante).

De plus, certaines choses peuvent être faites avec typedef et ne peuvent pas être faites avec define.

Exemples:

typedef int* int_p1;
int_p1 a, b, c;  // a, b, and c are all int pointers.

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer!

.

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
207
Andreas Grech

Non, ils ne sont pas les mêmes. Par exemple:

#define INTPTR int*
...
INTPTR a, b;

Après le prétraitement, cette ligne est étendue à

int* a, b;

J'espère que vous voyez le problème; seul a aura le type int *; b sera déclaré en clair int (car le * est associé au déclarant, pas au spécificateur de type). 

Contraste cela avec

typedef int *INTPTR;
...
INTPTR a, b;

Dans ce cas, a et b auront le type int *

Il existe des classes entières de typedefs qui ne peuvent pas être émulées avec une macro de pré-processeur, telles que les pointeurs sur des fonctions ou des tableaux:

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

Essayez de faire cela avec une macro de préprocesseur. 

21
John Bode

#define définit les macros.
typedef définit les types.

Maintenant, en disant cela, voici quelques différences:

Avec #define, vous pouvez définir des constantes pouvant être utilisées lors de la compilation. Les constantes peuvent être utilisées avec #ifdef pour vérifier comment le code est compilé et spécialiser certains codes en fonction des paramètres de compilation.
Vous pouvez également utiliser #define pour déclarer une fonction de recherche et de remplacement miniature Fonctions macro.

typedef peut être utilisé pour donner des alias à des types (ce que vous pourriez probablement faire avec #define également), mais c'est plus sûr en raison de la nature de recherche/remplacement des constantes #define .
De plus, vous pouvez utiliser forward declaration avec typedef qui vous permet de déclarer un type qui sera utilisé, mais qui n'est pas encore lié au fichier que vous écrivez. dans.

12
Yochai Timmer

Les macros de préprocesseur ("#define 's") sont un outil de remplacement lexical comme "rechercher et remplacer". Ils sont totalement agnostiques du langage de programmation et ne comprennent pas ce que vous essayez de faire. Vous pouvez les considérer comme un mécanicien de copier/coller glorifié - c'est utile parfois, mais vous devez l'utiliser avec précaution.

Les typedefs sont une fonctionnalité du langage C qui vous permet de créer des alias pour les types. Ceci est extrêmement utile pour rendre des types composés compliqués (comme des structures et des pointeurs de fonction) lisibles et manipulables (en C++, il existe même des situations où vous devez typedef un type).

Pour (3): Vous devriez toujours préférer les fonctionnalités de langage aux macros du préprocesseur lorsque cela est possible! Il faut donc toujours utiliser typedefs pour les types et valeurs constantes pour les constantes. De cette façon, le compilateur peut réellement interagir avec vous. Rappelez-vous que le compilateur est votre ami, vous devriez donc le dire autant que possible. Les macros de préprocesseur font exactement le contraire en cachant votre sémantique au compilateur.

5
Kerrek SB

Ils sont très différents, bien qu'ils soient souvent utilisés pour implémenter des types de données personnalisés (c'est en cela que je suppose que cette question est tout entière).

Comme mentionné par pmg, #define est traité par le préprocesseur (comme une opération copier-coller) avant que le compilateur voie le code, et typedef est interprété par le compilateur.

L'une des principales différences (du moins lorsqu'il s'agit de définir des types de données) est que typedef permet une vérification de type plus spécifique. Par exemple,

#define defType int
typedef int tdType

defType x;
tdType y;

Ici, le compilateur voit la variable x comme un int, mais la variable y comme un type de données appelé 'tdType' qui se trouve être de la même taille qu'un int. Si vous avez écrit une fonction prenant un paramètre de type defType, l'appelant pourrait transmettre un int normal et le compilateur ne saurait pas la différence. Si la fonction prend plutôt un paramètre de type tdType, le compilateur s'assurera qu'une variable du type approprié est utilisée lors des appels de fonction.

De plus, certains débogueurs ont la capacité de gérer typedefs, ce qui peut être beaucoup plus utile que d'avoir tous les types personnalisés répertoriés comme types primitifs sous-jacents (comme ce serait le cas si #define était utilisé à la place).

3
bta

Non. 
typedef est un mot clé C qui crée un alias pour un type.
#define est une instruction de pré-processeur, qui crée un événement de remplacement de texte avant la compilation. Lorsque le compilateur obtient le code, le mot "#defined" d'origine n'est plus là. #define est principalement utilisé pour les macros et les constantes globales.

2

Autant que je sache, non 

'typedef' vous aide à configurer un "alias" pour un type de données existant. Pour par exemple. typedef char chr; 

#define est une directive préprocesseur utilisée pour définir des macros ou des substitutions de modèles généraux. Pour par exemple. #define MAX 100, remplace toutes les occurrences de MAX par 100

1
user59634

Comme tout le monde l'a dit plus haut, ils ne sont pas les mêmes. La plupart des réponses indiquent que typedef est plus avantageux que #define. Mais laissez-moi mettre un point positif de #define:
lorsque votre code est extrêmement volumineux et dispersé dans de nombreux fichiers, il est préférable d’utiliser #define; cela aide à la lisibilité - vous pouvez simplement prétraiter tout le code pour voir la définition de type réelle d’une variable à la place de sa déclaration elle-même.

0
abcoep