L’utilisation de la macro entraîne une sortie incorrecte lorsqu’elle est utilisée dans le cadre d’une expression mathématique plus grande. Pourquoi cela se produit-il?

C’est un programme de routine C normal que j’ai découvert dans une banque de questions. Il est montré ci-dessous:

#define CUBE(p) p*p*p main() { int k; k = 27 / CUBE(3); printf("%d", k); } 

Selon ma compréhension et ma connaissance, la valeur de K devrait être 1, car CUBE (3) serait remplacé par 3 * 3 * 3 lors du prétraitement. Après la compilation ultérieure, il donnerait la valeur 1, mais à la place, il a montré la valeur. de 81 qui m’a rendu curieux de savoir comment cela s’est passé.

Quelqu’un peut-il s’il vous plaît justifier la réponse de 81 à cette question ci-dessus.

Les pré-processeurs doivent être correctement parenthèses. Le remplacer par

 #define CUBE(p) ((p)*(p)*(p)) 

et voir.

Le préprocesseur ne fait que substituer

 CUBE(3) 

avec

 3*3*3 

Donc vous vous retrouvez avec:

 k=27/3*3*3 

Qui, évalué de gauche à droite avec la priorité de l’opérateur, est en fait 81.

Si vous ajoutez des parenthèses autour de la macro, vous constaterez que les résultats sont corrects:

 #define CUBE(p) (p*p*p) 

Il serait même préférable d’entourer chaque instance de p avec des parenthèses, comme dans:

 #define CUBE(p) ((p)*(p)*(p)) 

Ce qui vous permettra de transmettre des expressions à la macro correctement (par exemple, 1 + 2 ).

En raison de la priorité de l’opérateur 27/3 27/3*3*3 = 81

Vous pouvez utiliser à la place:

 inline int cube(int p) { return p*p*p; } 

Les macros C font une substitution textuelle (c’est-à-dire que cela équivaut à copier et coller du code). Donc, votre code va de:

 k=27/CUBE(3); 

à

 k=27/3*3*3; 

La division et la multiplication ont la même priorité et ont une associativité de gauche à droite, elles sont donc analysées comme suit:

 k=((27/3)*3)*3; 

qui est 9 * 3 * 3 = 81.

C’est pourquoi les macros C doivent toujours être définies avec une utilisation généralisée des parenthèses:

 #define CUBE(p) ((p) * (p) * (p)) 

Pour plus d’informations, voir http://c-faq.com/cpp/safemacros.html à partir de la FAQ comp.lang.c.

Les macros étant une substitution textuelle, cela fonctionne comme suit:

 k = 27 / 3 * 3 * 3; 

Puisque la multiplication et la division se produisent de gauche à droite, cela revient à:

 k = ((27 / 3) * 3) * 3; 

Donc, vous voulez changer cela de deux manières:

 #define CUBE(p) ((p)*(p)*(p)) 

Les parenthèses externes provoquent les multiplications avant toute autre opération.

Les parenthèses entourant les différents p sont pour le cas où vous faites:

 CUBE(1 + 2); 

Sans ces parenthèses internes, la priorité des opérateurs vous tracassera.

Votre macro n’est pas protégée. Essayer

 #define CUBE(p) ((p)*(p)*(p)) 

La macro actuelle a été étendue à

 k=27/3*3*3 

qui est ((27/3) * 3) * 3

 k=27/CUBE(3); => k=27/3 * 3 * 3; 

Est-ce que tu le vois? CUBE devrait être défini comme ceci à la place:

 #define CUBE(p) ((p)*(p)*(p)) 

Lorsque vous faites des macros, vous devez faire attention à la manière dont vous placez des parenthèses. Dans ce cas, vous n’en avez pas, l’expression devient 27/3 * 3 * 3, ce qui, selon les règles de priorité de / et *, devient (27/3) * 3 * 3.

27/3 * 3 * 3 = 9 * 3 * 3 = 81?

Les deux opérateurs / et * ont la même priorité. Pour exécuter 3 * 3 * 3 d’abord, vous devez les inclure entre parenthèses.

 #include  #define CUBE(p) p*p*p int main () { int k; k=27/(CUBE(3)); printf("%d",k); return 0; } 
  #define CUBE(p) p*p*p main() { int k; k=27/CUBE(3); printf("%d",k); } 

Selon ma compréhension et ma connaissance, la valeur de K devrait être 1, car CUBE (3) serait remplacé par 3 * 3 * 3 lors du prétraitement.

OUI

et après la compilation ultérieure, cela donnerait la valeur 1, mais plutôt la valeur 81, ce qui m’a rendu curieux de savoir comment cela se passait.

NON,

 k= 27/3*3*3 =(((27/3)*3)*3) (The precedence of `*` and `/` are same but the associativity is from left to right) =((9*3)*3) =81 

Remplacez #define CUBE(p) p*p*p par #define CUBE(p) ((p)*(p)*(p))

c’est la manière dont l’associativité et la préséance des opérateurs sont mises en œuvre. lorsque l’expression est développée, elle devient 27/3 * 3 * 3 et non 27 / (3 * 3 * 3) , division et multiplication ont la même priorité en C, mais leur associativité est gauche à droite. ainsi on peut montrer que: (27/3) * 3 * 3 qui à son tour est égal à (9 * 3) * 3 = 81 est l’ordre de priorité, alors nous faisons la division d’abord, puis la multiplication. Nous obtenons donc à nouveau la réponse en tant que 81 pour 27/3 * 3 * 3.

La réponse à cette question est la suivante: 81 Explication: À l’étape k = 27 / cube (3), le cube (3) est remplacé par 3 * 3 * 3 par le préprocesseur. L’instruction ci-dessus devient alors k = 27/3 * 3 * 3 L’expression 27/3 est évaluée par le compilateur c (priorité des opérateurs). Le résultat est (27/3): 9 l’instruction k = 27/3 * 3 * 3 devient k = 9 * 3 * 3; le résultat de la déclaration ci-dessus est 81: