¿Cómo funciona el preprocesador en C?

¿Por qué es la respuesta para el siguiente código 16? ¿Alguien puede explicar el funcionamiento de este progtwig?

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

Si escribimos el mismo código como abajo, entonces la respuesta es 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(); } 

obtendrás

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

El preprocesador simplemente reemplaza el texto, exactamente como está escrito.

Entonces, la macro llamada SQUARE(2) convierte literalmente en 2*2 .

En su caso, eso significa que toda la expresión se convierte en 16/2 16/2*2 , que debido a las reglas de precedencia de C se evalúa como (16/2) * 2, es decir, 16.

Las macros siempre deben estar entre paréntesis, y también se deben incluir todos los argumentos.

Si hacemos eso, obtenemos:

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

que reemplaza a 16/((2) * (2)) , que se evalúa como 16/4, es decir, 4.

El paréntesis alrededor de cada argumento hace que cosas como SQUARE(1+1) funcione como se espera, sin ellos una llamada como 16/SQUARE(1+1) se convertirá en 16/(1+1*1+1) que es 16/3 , es decir, en absoluto lo que quieras.

Orden de operaciones. Tu expresión está evaluando a:

  j = 16 / 2 * 2 

que es igual a 16. Hazlo:

 #define SQUARE(n) (n*n) 

Lo que obligará al cuadrado a ser evaluado primero.

Necesitas definir tu macro con paréntesis aislantes, así:

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

De otra manera

  j = 16/SQUARE(2); 

se expande a

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

Cuando lo que quieres es

 j = 16 / (2 * 2); 

1. Cuando use macros que se usarán como expresiones, debe paréntesis todo el cuerpo de la macro.

Esto evita expansiones erróneas como:

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

2. Si los argumentos de macro son expreessions, también debe paréntesis.

Esto evita un tipo diferente de problemas:

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

Por lo tanto, la forma correcta es escribirlo así:

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

Sin embargo, no se recomienda el uso de macros como funciones (adivina por qué), así que usa una función en su lugar. Por ejemplo:

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

La expansión de la macro será como:

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

Que es igual a: j = (16/2)*2; Significa j = 16;

y:

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

Que es igual a: j = 16/4; Significa j = 4;

Porque la macro se ampliará como:

 j = 16/2*2; 

El precomstackdor no realiza ningún procesamiento en la expansión. Coloca la macro expandida en tu código tal como es. Ya que no ha entre paréntesis el texto de reemplazo, tampoco lo hará por usted en el código principal. Hazlo :

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

El primer ejemplo se evalúa como:

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

El segundo ejemplo se evalúa como:

 16 / (2 * 2) 16 / 4 4 

Agregue paréntesis a su statement del preprocesador para controlar el orden de las operaciones:

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

Los paréntesis externos en ((n) * (n)) aseguran que n esté cuadrada antes de realizar cualquier operación externa. El paréntesis interno (n) garantiza que n se evalúa correctamente en los casos en los que se pasa una expresión a SQUARE como:

 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