Comment fonctionne le pré-processeur en C?

Pourquoi la réponse pour le code ci-dessous 16? Quelqu’un peut-il expliquer le fonctionnement de ce programme?

#define SQUARE(n) n*n void main() { int j; j =16/SQUARE(2); printf("\nj=%d",j); getch(); } 

Si nous écrivons le même code que ci-dessous, alors la réponse est 4:

 //the ans is 4 why? #include #include #define SQUARE(n) n*n void main() { int j; j =16/(SQUARE(2)); printf("\nj=%d",j); getch(); } 

tu auras

 j =16/2*2; // (16 / 2) * 2 = 16 

Le préprocesseur remplace simplement le texte, exactement comme il a été écrit.

Ainsi, l’appel de macro SQUARE(2) devient littéralement 2*2 .

Dans votre cas, cela signifie que l’expression entière devient 16/2 16/2*2 , ce qui, en raison des règles de priorité de C, est évaluée à (16/2) * 2, c’est-à-dire 16.

Les macros doivent toujours être entre parenthèses et chaque argument également.

Si nous faisons cela, nous obtenons:

 #define SQUARE(n) ((n) * (n)) 

qui remplace 16/((2) * (2)) , qui est évalué à 16/4, soit 4.

Les parenthèses autour de chaque argument font que des choses comme SQUARE(1+1) fonctionnent comme prévu. Sans elles, un appel tel que 16/SQUARE(1+1) deviendrait 16/(1+1*1+1) ce qui est 16/3 , c’est-à-dire pas du tout ce que vous voudriez.

Ordre des opérations. Votre expression évalue à:

  j = 16 / 2 * 2 

qui est égal à 16. Faites-le:

 #define SQUARE(n) (n*n) 

ce qui forcera le carré à être évalué en premier.

Vous devez définir votre macro avec des parenthèses isolantes, comme suit:

  #define SQUARE(n) ((n)*(n)) 

Autrement

  j = 16/SQUARE(2); 

s’étend à

 j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2 

Quand ce que tu veux c’est

 j = 16 / (2 * 2); 

1. Lorsque vous utilisez des macros qui doivent être utilisées comme expressions, vous devez mettre entre parenthèses tout le corps de la macro.

Cela évite les extensions erronées telles que:

 #define SQUARE(x) x*x -SQUARE(5,5) // becomes -5 * 5 

2. Si les arguments de macro sont des expressions, vous devez également les mettre entre parenthèses.

Cela évite un type de problèmes différent:

 #define SQUARE(x) x*x SQUARE(5+2) // becomes 5 + 2*5 + 2 

Par conséquent, la méthode correcte consiste à l’écrire comme ceci:

 #define square(n) ((n)*(n)) -SQUARE(5+2) // becomes -((5+2)*(5+2)) 

L’utilisation de macros en tant que fonctions est toutefois déconseillée (devinez pourquoi), utilisez donc une fonction à la place. Par exemple:

 inline double square(n) { return n*n; } 

L’expansion de la macro sera comme:

  j = 16/SQUARE(2); j = 16/2*2; 

Ce qui est égal à: j = (16/2)*2; Signifie j = 16;

et :

  j = 16/(SQUARE(2)); j = 16/(2*2); 

Ce qui est égal à: j = 16/4; Signifie j = 4;

Parce que la macro sera développée comme suit:

 j = 16/2*2; 

Le pré-compilateur ne fait aucun traitement sur l’extension. Il place la macro développée dans votre code tel quel. Puisque vous n’avez pas mis le texte de remplacement entre parenthèses, il ne le fera pas non plus pour vous dans le code principal. Fais-le :

 #define SQUARE(n) ((n)*(n)) 

Le premier exemple est évalué comme suit:

 16 / 2 * 2 (16 / 2) * 2 8 * 2 16 

Le deuxième exemple est évalué comme suit:

 16 / (2 * 2) 16 / 4 4 

Ajoutez des parenthèses à votre déclaration de préprocesseur pour contrôler l’ordre des opérations:

 #define SQUARE(n) ((n)*(n)) 

La parenthèse externe dans ((n) * (n)) garantit que n est carré avant toute opération extérieure. La parenthèse interne (n) assure que n est correctement évalué dans les cas où vous passez une expression à SQUARE comme ceci:

 16 / SQUARE(2 * 2) 16 / ((2 * 2)*(2 * 2)) 16 / (4 * 4) 16 / 16 1 
 Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro. Case 1 : result 16 define SQUARE(n) n*n void main() { int j; j =16/SQUARE(2); printf("\nj=%d",j); getch(); } its get expand as below j =16/SQUARE(2); so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n j = 16/2*2 j = (16/2)*2 j = 8*2 j =16 Case 2 : result 4 define SQUARE(n) n*n void main() { int j; j =16/(SQUARE(2)); printf("\nj=%d",j); getch(); } its get expand as below j =16/(SQUARE(2)); so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n j = 16/(2*2) j = 16/(4) j = 4 Hope this will help