2010-09-15 18 views
9

Estaba revisando cierto código que se pregunta con frecuencia en las entrevistas. Se me ocurrieron ciertas preguntas, si alguien puede ayudarme con respecto a esto.Cuadrado de un número que se define usando #define

estoy totalmente confundido en este momento,

#include <stdio.h> 
#include <conio.h> 

#define square(x) x*x 

main() 
{ 
     int i, j; 
     i = 4/square(4); 
     j = 64/square(4); 
     printf("\n %d", i); 
     printf("\n %d", j); 
     printf("\n %d", square(4)); 
     getch(); 
} 

La salida es:

4 
64 
16 

Me pregunto, ¿por qué square(4) retorno 1 cuando la dividí? Quiero decir, ¿cómo puedo obtener el valor 4 y 64 cuando lo divido, pero cuando lo uso directamente obtengo !!?

+1

Solo para tener en cuenta que #define square (x) x * x es un clasdy C baddy. Pruebe un ciclo con cuadrado (x ++); – Jaydee

+5

Si realmente quiere confundirse y aún no ha leído ninguna de las respuestas, intente reemplazar 'square (4)' en todas partes con 'square (3 + 1)'. – JeremyP

+0

Este fue un problema de precedencia simple. –

Respuesta

26

square es bajo-entre paréntesis: se expande textualmente, por lo

#define square(x) x*x 
    ... 
i=4/square(4); 

significa

i=4/4*4; 

qué grupos como (4/4) * 4.Para corregir, añadir paréntesis:

#define square(x) ((x)*(x)) 

Todavía un muy dudoso #define ya que evalúa x dos veces, así square(somefun()) llama a la función dos veces y hace no por lo tanto, necesariamente calcular un cuadrado sino más bien el producto de las dos llamadas consecutivas, por supuesto;-).

+0

sí ... lo tengo ... se estaba volviendo loco por eso ... –

+3

+1 por 'cuadrado (somefun())'. La observación habitual en ese caso es sobre el efecto secundario realizado dos veces, pero si imagina 'cuadrado (rand())' obtendrá el producto de dos números aleatorios, no el cuadrado de un solo número aleatorio. – RBerteig

2

La precedencia del operador te está perjudicando.

La macro se expande por el preprocesador de tal manera que

i=4/4*4; 
    j=64/4*4; 

lo que equivale a:

i=(4/4)*4; 
    j=(64/4)*4; 
1

j = 4/square(4) == 4/4*4 == 1*4 == 4

4

Cuando se escribe i=4/square(4), el preprocesador se expande a que i = 4/4 * 4 .
Dado que C agrupa las operaciones de izquierda a derecha, el compilador interpreta eso como i = (4/4) * 4, que es equivalente a 1 * 4.

es necesario agregar paréntesis, así:

#define square(x) ((x)*(x)) 

De esta manera, se convierte en i=4/square(4)i = 4/((4) * (4)).
Se necesita el paréntesis adicionales alrededor x en caso de que usted escribe square(1 + 1), que de otra manera convertirse en 1 + 1 * 1 + 1, que se evalúa como 1 + (1 * 1) + 1 o 3.

3
i=4/square(4); 

expande a

i=4/4*4; 

que equivale a

i=(4/4)*4; 
0

expandir manualmente el macro en el código, y será claro. Es decir, reemplace todo el cuadrado (x) con exactamente x * x, en particular, no agregue ningún paréntesis.

0

definir es sólo un texto macro

main() 
{ 
     int i,j; 
     i=4/ 4 * 4; // 1 * 4 
     j=64/4 * 4; // 16 * 4 
     printf("\n %d",i); 
     printf("\n %d",j); 
     printf("\n %d",square(4)); 
     getch(); 
} 
0

Es una macro! Por lo tanto, devuelve exactamente lo que sustituye.

i = 4/4*4; Which is 4... 
j = 64/4*4; Which is 16... 

probar esto por su macro:

#define square(x) ((x)*(x)) 
0

Debido a la precedencia de operadores en la expresión después de que el preprocesador - se necesita para escribir

#define square(x) (x*x) 
0

Como dicen las otras respuestas, estás siendo quemado por la precedencia del operador. Cambie su macro cuadrada a esto:

#define square(x) (x*x) 

y funcionará de la manera que usted espera.

2

Eso es porque el compilador reemplaza con:

i=4/4*4; 
j=64/4*4; 

i = (4/4) * 4 = 1 * 4 = 4.

j = (64/4) * 4 = 16 * 4 = 64.