#Define VS Variable

Je ne peux pas comprendre quelle est la différence entre:

#define WIDTH 10 

et

 int width = 10; 

Quels sont les avantages d’utiliser le premier ou le second?

Eh bien, il y a une grande différence. Vous pouvez modifier la valeur de width , vous pouvez prendre son adresse, vous pouvez demander sa taille, etc. Avec WIDTH , il sera simplement remplacé par une constante 10 partout, donc l’expression ++WIDTH n’a pas de sens. De l’autre côté, vous pouvez déclarer un tableau avec des éléments WIDTH , alors que vous ne pouvez pas déclarer un tableau avec des éléments de width .

En résumé: la valeur de WIDTH est connue au moment de la compilation et ne peut pas être modifiée. Le compilateur n’alloue pas de mémoire pour WIDTH . Au contraire, width est une variable de valeur initiale 10, ses autres valeurs ne sont pas connues au moment de la compilation. la variable tire sa mémoire du compilateur.

Quelle est la différence entre deux?

Le premier est une macro tandis que le second est une déclaration de variable.

#define WIDTH 10 est une directive de préprocesseur qui vous permet de spécifier un nom ( WIDTH ) et son texte de remplacement ( 10 ). Le préprocesseur parsing le fichier source et chaque occurrence du nom est remplacée par le texte qui lui est associé. Le compilateur ne voit jamais réellement un nom de macro, mais le texte remplacé.

La déclaration de variable est évaluée par le compilateur lui-même. Il indique au compilateur de déclarer une variable nommée width et de type int et l’initialise également avec la valeur 10 .
Le compilateur connaît cette variable par son propre nom de width .

Lequel devriez-vous préférer? Et pourquoi?

En général, il est recommandé d’utiliser des variables de constante de temps de compilation sur #define . Donc, votre déclaration de variable devrait être:

 const int width = 10; 

Il y a un certain nombre de raisons pour choisir les constantes de temps de compilation sur #define , à savoir:

Mécanisme basé sur la scope:

La scope de #define est limitée au fichier dans lequel elle est définie. Ainsi, les #defines dans un fichier source NE sont PAS disponibles dans un fichier source différent. En bref, #define s ne respecte pas les scopes. Notez que les variables const peuvent être étendues. Elles obéissent à toutes les règles de scope.


Eviter les nombres étranges lors des erreurs de compilation:

Si vous utilisez #define ceux-ci sont remplacés par le pré-processeur au moment de la précompilation. Ainsi, si vous recevez une erreur lors de la compilation, cela sera source de confusion, car le message d’erreur ne fera pas référence au nom de la macro mais à la valeur, et affichera une valeur soudaine. , et on perdrait beaucoup de temps à le retrouver dans le code.


Facilité de débogage:

En outre, pour les mêmes raisons que celles mentionnées au point 2, le débogage de #define ne fournirait aucune aide.

WIDTH est une macro qui sera remplacée par la valeur (10) par le préprocesseur alors que width est une variable.

Lorsque vous définissez une macro (comme ici WIDTH), le préprocesseur effectuera simplement un remplacement de texte avant que le programme ne soit transmis au compilateur. C’est-à-dire que partout où vous avez utilisé WIDTH dans votre code, il sera simplement remplacé par 10 .

Mais quand vous faites int width=10 , la variable est en vie

Tout d’abord, un bref arrière-plan: avant d’être compilé , un fichier C est prétraité . Le pré-processeur vérifie les instructions #include et #define .

Dans votre cas, cette instruction #define indique au pré-processeur de changer chaque chaîne WIDTH de votre code source avec la chaîne 10 . Lorsque le fichier sera compilé à l’étape suivante, chaque occurrence de WIDTH sera en réalité de 10 . Maintenant, la différence entre

 #define WIDTH 10 

et

 int width = 10; 

est que la première peut être vue comme une valeur constant , alors que la seconde est une variable normale dont la valeur peut être changée.

Une des #define est gérée par le pré-processeur, si elle trouve WIDTH dans le code source et la remplace par 10 , il ne fait que remplacer la base, entre autres choses, l’autre int width = 10; est géré par le compilateur, cela créera des entrées dans la table de recherche, générera des fichiers binarys pour allouer suffisamment de mémoire sur la stack, en fonction de sa définition, et copiera la valeur 10 dans cet emplacement de mémoire.

Ainsi, l’un n’est rien de plus qu’un libellé pour une constante, l’autre est une variable au moment de l’exécution.

Vous pouvez utiliser des pré-processeurs pour une exécution plus rapide, car les variables doivent être allouées sur la stack, au prix de ne pas être mutables au moment de l’exécution.

Vous utilisez généralement des préprocesseurs pour des choses qui n’ont pas besoin de changer au moment de l’exécution, mais attention, les préprocesseurs peuvent être un peu difficiles à déboguer, car ils peuvent réellement manipuler le code source avant qu’il ne soit transmis au compilateur, ce qui conduit à des bugs très subtils , cela peut ou peut ne pas être apparent en examinant le code source.

Définir est comme une scope de définition globale statique. Il ne doit pas être changé ou remplacé en tant que variable normale.