views:

186

answers:

11

Hi,

I was just going through certain code's which are frequently asked in Interview's. I came up with certain doubts, if anyone can help me regarding this? I am totally confused on this now,

#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();
}

Output is :

 4
 64
 16

I am wondering, why did square(4) return 1 when i divided it? i mean how can i get the value 4 and 64 when i divide it but when used directly i get 16!!?

+1  A: 

Operator precedence is hurting you.

The macro is expanded by the pre-processor such that

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

which is equivalent to:

  i=(4/4)*4;
  j=(64/4)*4;
Rowland Shaw
+1  A: 

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

a1ex07
+3  A: 

When you write i=4/square(4), the preprocessor expands that to i = 4 / 4 * 4.
Because C groups operations from left to right, the compiler interprets that as i = (4 / 4) * 4, which is equivalent to 1 * 4.

You need to add parentheses, like this:

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

This way, i=4/square(4) turns into i = 4 / ((4) * (4)).
You need the additional parentheses around x in case you write square(1 + 1), which would otherwise turn into 1 + 1 * 1 + 1, which is evaluated as 1 + (1 * 1) + 1, or 3.

SLaks
+3  A: 
i=4/square(4);

expands to

i=4/4*4; 

which equivalent to

i=(4/4)*4;
Vladimir
A: 

Manually expand the macro in the code, and it will be clear. That is, replace all the square(x) with exactly x*x, in particular don't add any parentheses.

Geoff Reedy
+18  A: 

square is under-parenthesized: it expands textually, so

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

means

i=4/4*4;

which groups as (4/4) * 4. To fix, add parentheses:

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

Still a very iffy #define as it evaluates x twice, so square(somefun()) calls the function twice and does not therefore necessarily compute a square but rather the product of the two successive calls, of course;-).

Alex Martelli
@Alex yea.. got it.. was getting mad over it..
Nagaraj Tantri
+1 for `square(somefun())`. The usual observation in that case is about side effect done twice, but if you imagine `square(rand())` you are getting the product of two random numbers, not the square of a single random number.
RBerteig
A: 

define is just a text 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();
}
Tim Hoolihan
A: 

It's a macro! So it returns exactly what it substitutes.

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

Try this for your macro:

#define square(x) ((x)*(x))
Starkey
A: 

Because of operator precedence in the expression after the preprocessor - you'll need to write

#define square(x) (x*x)
Ivo
A: 

As the other answers say, you're getting burned by operator precedence. Change your square macro to this:

#define square(x) (x*x)

and it'll work the way you expect.

paleozogt
+2  A: 

That's because the compiler replaces it with:

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

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

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

rursw1