Question

On m'a posé une question en C hier soir et je ne connaissais pas la réponse car je n'ai pas beaucoup utilisé le C depuis l'université, alors j'ai pensé que je pourrais peut-être trouver la réponse ici au lieu de simplement l'oublier.

Si une personne a une définition telle que:

#define count 1

Cette personne peut-elle trouver le nom de variable count en utilisant le 1 qu'il contient?

Je ne le pensais pas puisque je pensais que le décompte indiquerait le 1, mais je ne vois pas comment le 1 pourrait indiquer le décompte.

Était-ce utile?

La solution

La réponse simple est non, ils ne peuvent pas. #Defines comme ça sont traités par le pré-processeur, et ils ne pointent que dans une direction. Bien sûr, l’autre problème est que même le compilateur ne le saurait pas - en tant que "1" peut pointer sur n'importe quoi - plusieurs variables peuvent avoir la même valeur en même temps.

Autres conseils

S'appuyant sur la réponse de @Cade Roux, si vous utilisez un préprocesseur #define pour associer une valeur à un symbole, le code n'aura aucune référence au symbole une fois que le préprocesseur aura été exécuté:

#define COUNT (1)
...
int myVar = COUNT;
...

Après l'exécution du préprocesseur:

...
int myVar = (1);
...

Comme d'autres l'ont déjà noté, cela signifie "non" pour la raison ci-dessus.

  
    

Cette personne peut-elle trouver le nom de variable " count " en utilisant le 1 qui est à l'intérieur?

  

Non

Comme je suis sûr que quelqu'un de plus éloquent et versé que moi soulèvera # les choses définies ne sont pas compilées dans la source, ce que vous avez est une macro de pré-processeur qui va parcourir la source et changer toutes les instances. de "compter" il trouve avec un '1'.

Toutefois, pour éclairer davantage la question qui vous a été posée, car C est un langage compilé jusqu’au code machine, vous ne garderez jamais le reflet et l’introspection que vous avez avec un langage comme Java ou C #. Toute la dénomination est perdue après la compilation, sauf si vous avez un framework construit autour de votre source / compilateur pour faire des choses astucieuses.

J'espère que cela vous aidera. (excusez le jeu de mots)

Malheureusement, cela n'est pas possible.

Les instructions

#define sont des instructions destinées au préprocesseur. Toutes les instances de count sont remplacées par 1 . Au moment de l'exécution, il n'y a pas d'emplacement de mémoire associé à count , l'effort est donc évidemment inutile.

Même si vous utilisez des variables, il ne restera plus, après la compilation, d'identificateurs d'origine utilisés dans le programme. Cela n’est généralement possible que dans les langages dynamiques.

Une astuce utilisée en C consiste à utiliser la syntaxe # dans les macros pour obtenir le littéral chaîne du paramètre macro.

#define displayInt(val) printf("%s: %d\n",#val,val)
#define displayFloat(val) printf("%s: %d\n",#val,val)
#define displayString(val) printf("%s: %s\n",#val,val)

int main(){
  int foo=123;
  float bar=456.789;
  char thud[]="this is a string";

  displayInt(foo);
  displayFloat(bar);
  displayString(thud);

  return 0;
}

La sortie devrait ressembler à ceci:

foo: 123
bar: 456.789
thud: this is a string

#define count 1 est une très mauvaise idée, car elle vous empêche de nommer des variables ou des champs de structure count .

Par exemple:

void copyString(char* dst, const char* src, size_t count) {
   ...
}

Votre macro count provoquera le remplacement du nom de la variable par 1 , empêchant ainsi la compilation de cette fonction:

void copyString(char* dst, const char* src, size_t 1) {
   ...
}

Les définitions C sont une directive de pré-processeur, pas une variable. Le pré-processeur parcourt votre fichier C et remplace l'emplacement où vous écrivez compte avec ce que vous avez défini, avant la compilation. Examinez les entrées obscures du concours C pour des utilisations particulièrement éclairées de cette directive et d’autres directives relatives au préprocesseur.

Le fait est qu’il n’ya pas de "compte" pour pointer sur une valeur "1". C’est une simple opération de remplacement qui se produit avant que le code ne soit même réellement compilé.

Je laisserai ceci éditable à quelqu'un qui sait réellement que C doit corriger.

count n'est pas une variable. Aucune mémoire ne lui est allouée et aucune entrée dans la table des symboles. C'est une macro qui est remplacée par le préprocesseur avant de transmettre le code source au compilateur.

Si vous ne posez pas la bonne question, il existe un moyen d'obtenir le nom à l'aide de macros:

#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1

SHOW(count); // prints "count = 1"

L'opérateur # convertit un argument de macro en un littéral de chaîne.

#define est une directive de pré-processeur, en tant que telle, il ne s'agit pas d'une "variable"

.

Ce que vous avez n’est pas une variable, c’est une directive de préprocesseur. Lorsque vous compilez le code, le préprocesseur passe en revue et remplace toutes les occurrences du mot "count" dans ce fichier par 1.

Vous demandez peut-être si je sais 1 puis-je trouver que le nombre de points y correspond? Non, car la relation entre les noms de variables et les valeurs n'est pas une bijection, il n'y a pas de retour en arrière. Considérer

int count = 1;
int count2 = 1;

parfaitement légal, mais que doit-on résoudre?

En général, non.

Tout d'abord, une #define n'est pas une variable, c'est une macro du préprocesseur du compilateur.

Au moment où la phase principale du compilateur se met au travail, le nom a été remplacé par la valeur et le nom "count" n'existera nulle part dans le code compilé.

Pour les variables, il n'est pas possible de trouver les noms de variables dans le code C au moment de l'exécution. Cette information n'est pas conservée. Contrairement à des langages tels que Java ou C #, C ne conserve pas beaucoup de métadonnées, que ce soit en langage d'assemblage ou en langage assembleur.

Directive commençant par " # " sont traités par le pré-processeur qui effectue généralement la substitution de texte avant de transmettre le code au compilateur "réel". En tant que tel, il n’existe pas de variable appelée count, c’est comme si tous les "count" Les chaînes de votre code sont remplacées comme par magie par le symbole "1". chaîne.

Donc, non, pas moyen de trouver cette "variable".

Dans le cas d’une macro, cela est prétraité et la sortie résultante est compilée. Il est donc absolument impossible de connaître ce nom car, une fois que le préprocesseur aura terminé son travail, le fichier résultant contiendrait "1" au lieu de "compte" partout dans le fichier.

Donc, la réponse est non.

S'ils regardent le code source C (qu'ils seront dans un débogueur), ils verront quelque chose comme

int i = count;

à ce stade, ils peuvent rechercher en arrière et trouver la ligne

#define count 1

Si, cependant, tout ce qu’ils ont, c’est la variable iDontKnowWhat, et qu’ils peuvent le voir contenir le chiffre 1, il n’ya aucun moyen de le suivre pour le «décompter».

Pourquoi? Parce que #define est évalué au moment du préprocesseur, ce qui se produit même avant la compilation (bien que pour presque tout le monde, il peut être considéré comme la première étape de la compilation). Par conséquent, le code source est la seule chose qui contient des informations sur le «nombre», comme savoir qu'il a jamais existé. Au moment où le compilateur obtient un aperçu, chaque référence à «compte» a été remplacée par le nombre «1».

Ce n'est pas un pointeur, c'est juste une substitution chaîne / jeton. Le préprocesseur remplace toutes les #défines avant que votre code ne soit jamais compilé. La plupart des compilateurs incluent un argument -E ou similaire pour émettre du code précompilé. Vous pouvez ainsi voir à quoi ressemble le code après le traitement de toutes les # directives.

Plus directement à votre question, il n’est pas possible de savoir qu’un jeton est remplacé dans le code. Votre code ne peut même pas faire la différence entre (nombre == 1) et (1 == 1).

Si vous voulez vraiment faire cela, il est peut-être possible d'utiliser l'analyse de texte du fichier source, en utilisant par exemple un outil diff.

Qu'entendez-vous par "trouver"?

La ligne

#define count 1

définit un symbole " compte " qui a la valeur 1.

La première étape du processus de compilation (appelée prétraitement) remplacera chaque occurrence du nombre de symboles par 1, de sorte que si vous avez:

if (x > count) ...

il sera remplacé par:

if (x > 1) ...

Si vous obtenez cela, vous verrez peut-être pourquoi " find count " n'a pas de sens.

La personne qui pose la question (s’agissait-il d’une question d’entrevue?) a peut-être tenté de vous aider à faire la différence entre l’utilisation de constantes #define et d’énums. Par exemple:

#define ZERO 0
#define ONE 1
#define TWO 2

vs

enum {
  ZERO,
  ONE,
  TWO
};

Étant donné le code:

x = TWO;

Si vous utilisez des énumérations au lieu de #defines, certains débogueurs pourront vous montrer la forme symbolique de la valeur, TWO, au lieu de la valeur numérique uniquement 2.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top