48 votes

Type de variables #define

Si je l'ai fait :

#define MAXLINE    5000

Quel est le type de MAXLINE ? Dois-je supposer qu'il s'agit d'un int ? Puis-je le tester d'une manière ou d'une autre ?

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

54voto

tpg2114 Points 3675

Il n'a pas de type. Il s'agit d'une simple substitution de texte. Le texte 5000 sera déposé à la place partout où MAXLINE apparaît comme un token.

Par exemple :

int a = MAXLINE;

mettra la valeur 5000 dans a .

Alors que

char *MAXLINE2 = "MAXLINE";

n'entraînera pas

char *50002 = "5000";

Donc, si vous voulez un contrôle de type, les macros ne sont pas la solution. Vous voudrez déclarer des constantes statiques à la place, de cette façon la vérification du type est effectuée par le compilateur.

Pour plus d'informations sur les différences entre static , const y #define il existe de nombreuses sources, dont cette question : Static, define, et const en C

10voto

Andrew Edgecombe Points 13183

(Très !) En gros, votre compilateur C va effectuer 3 tâches lors de son exécution :

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

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

  3. Exécutez un éditeur de liens sur les fichiers objets résultants.

Les lignes commençant par un # J'aime la ligne

#define MAXLINE    5000

est géré par la phase de préprocesseur. (de manière simpliste) Le préprocesseur va analyser un fichier et effectuer des substitutions de texte pour toutes les macros qu'il détecte. Il n'y a pas de concept de type dans le préprocesseur.

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

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

Le préprocesseur détectera la macro MAXLINE à la ligne 2, et effectuera une substitution de texte. Notez qu'à la ligne 3 "MAXLINE" n'est pas traitée comme une macro, car il s'agit d'une chaîne littérale.

Une fois la phase de préprocesseur terminée, la phase de compilation ne verra que ce qui suit :

int someVariable = 5000;        // line 2
char someString[] = "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 permet de le faire.

Notez que bien que le préprocesseur n'ait pas de concept de type, il n'y a aucune raison pour que vous ne puissiez pas inclure un type dans votre macro par souci d'exhaustivité, par exemple

#define MAXLINE    ((int)5000)

5voto

Muath Ali Points 186

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/

3voto

Aaron McDaid Points 7761

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

#define APPEND(x,y) x ## y

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

Le préprocesseur le transforme en ceci avant de le passer au compilateur proprement dit :

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

Donc, juste parce que tu vois 5000 dans une macro, cela ne signifie pas qu'elle doive être numérique de quelque manière que ce soit.

3voto

David Alber Points 6205

MAXLINE n'est pas du tout une variable. En fait, ce n'est pas de la syntaxe C. Une partie du processus de compilation fait tourner un préprocesseur avant le compilateur, et l'une des actions du préprocesseur est de remplacer les instances de MAXLINE dans le fichier source avec tout ce qui suit #define MAXLINE (5000 dans le code de la question).

Par ailleurs, une autre façon courante d'utiliser le préprocesseur dans votre code est avec la fonction #include que le préprocesseur remplace simplement par le contenu prétraité du fichier inclus.

Exemple

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

#define VALUE 4

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

J'utilise gcc y cpp ( le préprocesseur C ) pour les exemples, mais vous pouvez probablement le faire avec n'importe quelle suite de compilateurs que vous avez, avec des drapeaux différents, bien sûr.

Compilation

Tout d'abord, nous allons compiler foo.c con gcc -o foo.c . Que s'est-il passé ? Cela a fonctionné ; vous devriez maintenant avoir un exécutable foo .

Prétraitement uniquement

Vous pouvez dire gcc pour ne faire que le prétraitement et ne pas faire de compilation. Si vous faites gcc -E foo.c vous obtiendrez le fichier prétraité sur la sortie standard. Voici ce qu'il produit :

# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "foo.c"

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

Remarquez que la première ligne de main a remplacé VALUE con 4 .

Vous vous demandez peut-être à quoi correspondent les quatre premières lignes. Il s'agit de marqueurs de ligne, et vous pouvez en savoir plus à ce sujet dans la rubrique Sortie du préprocesseur .

Compilation sans prétraitement

Pour autant que je sache, il n'est pas possible d'ignorer purement et simplement le prétraitement en gcc mais il existe quelques approches pour lui indiquer qu'un fichier a déjà été prétraité. Cependant, même si vous faites cela, il supprimera les macros présentes dans le fichier car elles ne sont pas destinées à être utilisées par le 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;
}

Remarque : j'ai mis les points en haut ; faites comme si c'étaient des lignes vides (j'ai dû les mettre là pour que ces lignes soient affichées par SO).

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X