开发者

Using macro results in incorrect output when used as part of a larger math expression - why does this happen?

开发者 https://www.devze.com 2022-12-17 00:14 出处:网络
This is a normal C routine program which i found out in some question bank. It is shown below: #define CUBE(p) p*p*p

This is a normal C routine program which i found out in some question bank. It is shown below:

#define CUBE(p) p*p*p

main()
{
    int k;
    k =开发者_Go百科 27 / CUBE(3);
    printf("%d", k);
}

As per my understanding and knowledge the value of K should be 1 as CUBE(3) would be replaced by 3*3*3 during preprocessing and after the subsequent compilation it would be giving the value of 1, but instead it has shown the value of 81 which has made me curious to know how it happened.

Can anyone please justify the answer of 81 to this question above.


The preprocessor merely substitutes

CUBE(3)

with

3*3*3

So you end up with:

k=27/3*3*3

Which, evaluated left-to-right with operator precedence, is in fact 81.

If you add parenthesees around the macro, you should find the results are correct:

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

It would be even better to surround each instance of p with parenthesees as well, as in:

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

Which will allow you to pass expressions to the macro correctly (for example, 1 + 2).


Because of operator precedence 27/3*3*3 = 81

You could use instead:

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


Preprocessors should be parenthesized properly. Replace it with

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

and see.


C macros do textual substitution (i.e. it's equivalent to copying and pasting code). So your code goes from:

k=27/CUBE(3);

to

k=27/3*3*3;

Division and multiplication have the same precedence and have left-to-right associativity, so this is parsed as:

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

which is 9 * 3 * 3 = 81.

This is why C macros should always be defined with liberal use of parentheses:

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

For more information, see http://c-faq.com/cpp/safemacros.html from the comp.lang.c FAQ.


Your macro is not protected. Try

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

The current macro was expanded to

k=27/3*3*3

which is ((27/3)*3)*3


Because macros are a textual substitution, that works out to:

k = 27 / 3 * 3 * 3;

Since multiplication and division happen left to right, that works out to:

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

So, you want to change that in two ways:

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

The outer parentheses cause the multiplications to be done before any other operations.

The parentheses around the individual p's are for the case where you do:

CUBE(1 + 2);

Without those inner parentheses, operator precedence will trip you up.


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

Do you see it? CUBE should be defined like this instead:

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


When you do macros, you have to be careful about how you place parentheses. In this case, you don't have any, so the expression becomes 27/3*3*3, which by the precedence rules of / and * becomes (27/3)*3*3.


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


Both / and * operators have the same precedence. To execure 3*3*3 first, you shoudl enclose them in parenthesis.

#include <stdio.h>

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

     }

As per my understanding and knowledge the value of K should be 1 as CUBE(3) would be replaced by 3*3*3 during preprocessing

YES

and after the subsequent compilation it would be giving the value of 1,but instead it has shown the value of 81 which has made me curious to know how it happenned.

NO,

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

Replace #define CUBE(p) p*p*p with #define CUBE(p) ((p)*(p)*(p))


its the way in which the associativity and precedence of operators is implemented. when the expression is expanded it becomes 27/3*3*3 and not 27/(3*3*3) now, division and multiplication both have the same precedence in C but the associativity is left to right for both. so it can be shown as : (27/3)*3*3 which in turn equals (9*3)*3 = 81 also, if u remember the old arithmetic rule of BODMAS(Bracket Off Division Multiplication Addition Subtraction), this is the order of precedence, then we do division first and then multiplication. so again we get answer as 81 for 27/3*3*3.


Hi answer for this is:81 Explanation: In step k=27/cube(3) cube(3) is replaced by 3*3*3 by preprocessor.then above statement becomes as k=27/3*3*3 in that 27/3 expression is evaluated by c compiler(operator precedence) the result is(27/3) :9 the statement k=27/3*3*3 becomes as k=9*3*3; the result for above statement is 81:

0

精彩评论

暂无评论...
验证码 换一张
取 消