Type de variables #define

Si j’ai:

#define MAXLINE 5000 

De quel type est entendu MAXLINE? Devrais-je supposer que c‘est un int ? Puis-je le tester d’une manière ou d’une autre?

En général, comment déterminer le type de variable #define ed?

Il n’a pas de type. C’est une simple substitution de texte. Le texte 5000 sera déposé à l’endroit où MAXLINE apparaît sous forme de jeton.

Par exemple:

 int a = MAXLINE; 

mettra la valeur 5000 dans a .

Tandis que

 char *MAXLINE2 = "MAXLINE"; 

n’entraînera pas

 char *50002 = "5000"; 

Donc, si vous voulez dactylographier, les macros ne sont pas la solution. Vous voudrez plutôt déclarer des constantes statiques, afin que la vérification du type soit effectuée par le compilateur.

Pour plus d’informations sur les différences entre static , const et #define , il existe de nombreuses sources, notamment la question suivante: Static, define et const en C

(Very!) Globalement, votre compilateur C va effectuer 3 tâches lorsqu’il est exécuté:

  1. Exécutez une passe de prétraitement sur vos fichiers source,

  2. Exécuter un compilateur sur les fichiers source prétraités

  3. Exécutez un éditeur de liens sur les fichiers d’object résultants.

Lignes commençant par # , comme la ligne

 #define MAXLINE 5000 

est géré par la phase de préprocesseur. (Simplistiquement) Le préprocesseur parsingra un fichier et effectuera des substitutions de texte pour toutes les macros détectées. Il n’y a pas de concept de types dans le préprocesseur.

Supposons que vous ayez les lignes suivantes dans votre fichier source:

 #define MAXLINE 5000 int someVariable = MAXLINE; // line 2 char someSsortingng[] = "MAXLINE"; // line 3 

Le préprocesseur détectera la macro MAXLINE sur la ligne 2 et effectuera une substitution de texte. Notez que sur la ligne 3, "MAXLINE" n’est pas traité comme une macro car il s’agit d’un littéral de chaîne.

Une fois la phase de préprocesseur terminée, la phase de compilation ne contiendra que les informations suivantes:

 int someVariable = 5000; // line 2 char someSsortingng[] = "MAXLINE"; // line 3 

(les commentaires ont été laissés pour plus de clarté, mais sont normalement supprimés par le pré-processeur) Vous pouvez probablement utiliser une option sur le compilateur pour pouvoir inspecter la sortie du pré-processeur. Dans gcc, l’option -E fera cela.

Notez que bien que le préprocesseur n’ait pas de concept de type, rien n’empêche d’inclure un type dans votre macro pour que celui-ci soit complet. par exemple

 #define MAXLINE ((int)5000) 

le compilateur ne voit jamais cette ligne de code, un pré-processeur s’exécute avant la compilation proprement dite et remplace ces macros par leurs valeurs littérales, voir le lien ci-dessous pour plus d’informations.

http://www.cplusplus.com/doc/tutorial/preprocessor/

Il n’a pas de type. C’est simplement un jeton que le préprocesseur mettra dans le code source avant de le transmettre au compilateur. Vous pouvez faire cette chose (ridicule) pour déclarer une variable appelée x5000 :

 #define APPEND(x,y) x ## y int main() { int APPEND(x,5000); x5000 = 3; } 

Le préprocesseur transforme cela en cela avant de le transmettre au compilateur proprement dit:

 int main() { int x5000; x5000 = 3; } 

Ainsi, le simple fait que vous voyez 5000 dans une macro ne signifie en aucun cas que celle-ci doit être numérique.

MAXLINE n’est pas une variable du tout. En fait, ce n’est pas la syntaxe C. Une partie du processus de compilation exécute un pré-processeur avant le compilateur, et l’une des actions de ce dernier consiste à remplacer les instances de jetons MAXLINE dans le fichier source par ce qui suit après #define MAXLINE (5000 dans le code de la question).

De plus, une autre manière courante d’utiliser le préprocesseur dans votre code consiste à utiliser la directive #include , que le préprocesseur remplace simplement par le contenu prétraité du fichier inclus.

Exemple

Regardons un exemple du processus de compilation en action. Voici un fichier, foo.c , qui sera utilisé dans les exemples:

 #define VALUE 4 int main() { const int x = VALUE; return 0; } 

J’utilise gcc et cpp ( le préprocesseur C ) pour les exemples, mais vous pouvez probablement le faire avec n’importe quelle suite de compilateur que vous avez, avec différents indicateurs, bien sûr.

Compilation

Commençons par comstackr foo.c avec gcc -o foo.c Qu’est-il arrivé? Ça a marché; vous devriez maintenant avoir un foo exécutable.

Prétraitement seulement

Vous pouvez indiquer à gcc de prétraiter uniquement et de ne faire aucune compilation. Si vous faites gcc -E foo.c , vous obtiendrez le fichier prétraité en sortie standard. Voici ce que cela produit:

 # 1 "foo.c" # 1 "" # 1 "" # 1 "foo.c" int main() { const int x = 4; return 0; } 

Notez que la première ligne de main a remplacé VALUE par 4 .

Vous vous demandez peut-être quelles sont les quatre premières lignes. Celles-ci sont appelées marqueurs de marques et vous pouvez en savoir plus à ce sujet dans Sortie du préprocesseur .

Compilation sans prétraitement

Autant que je sache, vous ne pouvez pas carrément ignorer le prétraitement dans gcc , mais il existe plusieurs approches pour lui dire qu’un fichier a déjà été prétraité. Même si vous faites cela, cependant, cela supprimera les macros présentes dans le fichier car elles ne sont pas destinées à la consommation du compilateur. Vous pouvez voir avec quoi le compilateur travaille dans cette situation avec gcc -E -fpreprocessed foo.c :

 . . . . int main() { const int x = VALUE; return 0; } 

Note: je mets les points en haut; prétendez que ce sont des lignes vides (je devais les mettre là pour que ces lignes soient affichées par SO).

Ce fichier ne sera clairement pas compilé (essayez gcc -fpreprocessed foo.c pour le savoir) car VALUE est présent dans la source, mais n’est défini nulle part.

Nous appelons cette macro ou préprocesseur, qui est utilisé pour remplacer par chaîne le contenu du fichier source. Lisez ceci: https://en.wikipedia.org/wiki/C_macro

Oui, vous pouvez supposer que c’est un int .

En fait, toutes les autres réponses sont correctes. Ce n’est pas C, c’est juste une directive qui demande au préprocesseur de faire des substitutions textuelles, et en tant que telle, elle n’a pas de type. Cependant, si vous ne faites pas de choses géniales avec lui (comme le truc du préprocesseur ##), vous utiliserez généralement MAXLINE comme une sorte de constante, et le pré-processeur le remplacera par 5000 ce qui est une constante explicite. Et les constantes ont le type: 5000 est un int . Une constante écrite sous la forme d’un entier décimal, sans suffixe (comme U ou L), sera interprétée par le compilateur comme un int , long int ou unsigned long int : le premier de ces types qui convient.

Mais cela n’a bien sûr rien à voir avec le préprocesseur. Vous pouvez réécrire votre question comme suit: «Quel est le type de 5000 ?», Sans #define .