Can someone explain to me why the value of y here is 13?
#include <stdio.h>
#define avg_sum(n) n * (n-1)/2
int main(){
int y;
int z = 9;
y = avg_sum(z+1);
printf("y=%i\n",y);
}
avg_sum(9+1) 9+1 * (9+1-1)/2 = 9 + 9/2 = 9+ 4 = 13
macros expand each time so 9+1 is not the same as 10, it might be better with safeguarding parenthesis as follows:
#define avg_sum(n) ((n) * ((n)-1)/2)
but an equivelant function will do you much better and be more intuitive and will evaluate arguments only once
avg_sum(a++) will be ((a++) * ((a++)-1)/2) and will increment a twice whereas a function will not have these issues since all arguments are evaulated before the function is called
The best way to answer these sorts of questions is to simply expand the macro in question:
y = avg_sum(z+1);
y = z + 1 * (z + 1 - 1) / 2
y = 9 + 1 * (9 + 1 - 1) / 2
y == 13
This is why you add parentheses around your macro arguments.
#define avg_sum(n) ((n) * ((n)-1)/2)
y = avg_sum(z+1);
expands to z + 1 * (z+1-1)/2 but it's wrong. Change your macro to
#define avg_sum(n) ((n) * ((n)-1)/2)
And always parenthesize as well arguments of functional macros as the macro itself . It's an important rule.
Related
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 6 years ago.
I defined a function using #define, but when I print out a simple result of an operation it gives me an unexpected result. Here is the code:
#include <stdio.h>
#define CUBE(x) (x * x * x)
int main() {
int m, n = 3;
m = CUBE(n + 1);
printf("%d %d", m, n--);
return 0;
}
The result printed is 10 and 3 and I can't understand why. Since it multiplies n by itself 3 times, and then adds 1, shouldn't the result be 28 and 3?
You don't #define functions, you #define macros, and those are quite different from functions.
They aren't called. They are expanded into the source code directly by the preprocessor, before the code is compiled by the compiler.
They have pitfalls that one must be aware of. To name one, if you pass an expression with side effects to a macro the uses its parameter more than once, the side effects will occur more than once, and you may get wrong results.
The substation is plain token substitution, so
CUBE(n + 1)
will be expand to this:
(n + 1 * n + 1 * n + 1)
#define CUBE(x) ((x) * (x) * (x))
should give you the expected result.
In your, on preprocessing, x in CUBE(x) is replaced by 3+1 which gives you
(3+1 * 3+1 * 3+1) // this happens during pre-processing, not in run time
as macro is plain-text replacement.
which will be grouped like
(3+(1 * 3)+(1 * 3)+1)
giving you 10. For more complex cases, I suggest writing a function.
As the previous answer already suggest, you are missing a pair of brackets,
because the preprocessor basically does find and replace. So your version result in
m = n + 1 * n + 1 * n + 1
which evaluates to the result, you observed.
With
#define CUBE(x) ((x) * (x) * (x))
you will get the correct calculation of
m = (n + 1) * (n + 1) * (n + 1)
#include<stdio.h>
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/SQUARE(t); // How is this evaluated ?
printf("Result %f\n",a);
return 0;
}
The output displayed by the compiler is -100.000000. But according to me it should be -25.000000. What should i do to correct it and what is my mistake?
#define does a literal substitution of the string of characters you have defined. So the expression:
a = 2*(s-u*t)/SQUARE(t*t)
Will expand to:
a = 2*(s-u*t)/t*t
Which, given operator order of evaluation, will evaluate as:
a = (2*(s-u*t)/t)*t
Not what you want. You probably really want a = 2*(s-u*t)/(t*t) so you should have:
#define SQUARE(x) (x*x)
Or even better, as #Jongware points out, since x itself could be an expression:
#define SQUARE(x) ((x)*(x))
That way, expressions like, SQUARE(a+b) will evaluate properly as ((a+b)*(a+b)), not (a+b*a+b).
Also as pointed out in comments, you need to beware of macro expression results when you have side effects in your arguments. For example, what does SQUARE(x++) do, and what is the value of x when it is done? In this case, it would give (x++)*(x++), with the value of x being post incremented twice and results may be undefined behavior (depends upon order of post increment in this case).
The preprocessor is a text replacement. So your expression becomes:
a=2*(s-u*t)/t*t;
* and / have equal precendence, so 2*(s-u*t) gets divided by t then multiplied by t.
Explanation:
The macro function SQUARE(x) x*x calculate the square of the given number 'x'.
Step 1: float s=10, u=30, t=2, a; Here the variable s, u, t, a are declared as an floating point type and the variable s, u, t are initialized to 10, 30, 2.
Step 2: a = 2*(s-u*t)/SQUARE(t); becomes,
=> a = 2 * (10 - 30 * 2) / t * t; Here SQUARE(t) is replaced by macro to t*t .
=> a = 2 * (10 - 30 * 2) / 2 * 2;
=> a = 2 * (10 - 60) / 2 * 2;
=> a = 2 * (-50) / 2 * 2 ;
=> a = 2 * (-25) * 2 ;
=> a = (-50) * 2 ;
=> a = -100;
Step 3: printf("Result=%f", a); It prints the value of variable 'a'.
Hence the output of the program is -100
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/t*t; // SQUARE(t) is defined as t*t so it is
// what is placed here instead of SQUARE(t)
Which is probably not what you want since /t*t==1.
SOLUTION:
#include<stdio.h>
#define SQUARE(x) ((x)*(x))
then:
#include<stdio.h>
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/((t)*(t)); // again, exactly as in #define SQUARE(t)
I read that * (multiplication) has has higher presedence than / (division). Thus if there is an equation with both * and /, then * must take place first.
But I've seen a program that output something strange
#include<stdio.h>
#define SQUARE(x) x*x
int main()
{
float s=10, u=30, t=2, a;
a = 2*(s-u*t)/SQUARE(t);
printf("Result = %f", a);
return 0;
}
When running this, I thought that the output would be -25, but in fact it was -100.
When I looked for the explanation it was
Step 2: a = 2*(s-u*t)/SQUARE(t); becomes,
// Here SQUARE(t) is replaced by macro to t*t
=> a = 2 * (10 - 30 * 2) / t * t;
=> a = 2 * (10 - 30 * 2) / 2 * 2;
=> a = 2 * (10 - 60) / 2 * 2;
=> a = 2 * (-50) / 2 * 2 ;
/*till here it's OK*/
/*why it divided -50 by 2 before multiplying 2*2 and -50*2 */
=> a = 2 * (-25) * 2 ;
=> a = (-50) * 2 ;
=> a = -100;
Can any one explain please?
Parenthesis paranoia! Your macro should be:
#define SQUARE(X) ((x)*(x))
Or else precedence rules and macro expansion will do weird things. Your macro:
100 / SQUARE(2)
will expand to:
100 / 2*2
and that is read as:
(100/2) * 2
which is 100, not 25.
Other anomaly, not in your code is if you try to square an expression:
SQUARE(2+2)
will expand to
2+2*2+2
which is 8, not the expected 16.
Conclusion: in macros write a lot of parentheses. Everywhere.
Division and muliplication have the same precedence, and are thus evaluated from left to right. http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
It does not do what you think it does: after the step marked /*till here it's OK*/, the operations proceed in their regular order for multiplicative operators, i.e. left to right:
=> a = 2 * (-50) / 2 * 2 ;
/*till here it's OK*/
=> a = -100 / 2 * 2 ; // Division
=> a = -50 * 2 ; // Multiplication
=> a = -100 ; // Done
Your code is a perfect example of why one needs to be very careful with macros: parenthesizing macro's parameters would fix this particular problem, but some problems are simply non-fixable. For example, your macro would remain unsuitable for expressions with side effects:
#define SQUARE(X) ((x)*(x))
// Still not good:
int a = 2;
// Undefined behavior, because ((a++)*(a++)) uses expressions with side effects without a sequence point
int b = SQUARE(a++);
For this reason, you would be better off making SQUARE a function.
This question already has answers here:
some error in output in using macro in C
(3 answers)
Closed 9 years ago.
Why doesn't this math work with macros in C?
#include <stdio.h>
#define FOO 6
#define BAR 32
#define MULT FOO * BAR
main() {
int x = 28296;
int y = x / MULT;
printf("%d / %d = %d\n", x, MULT, y);
return 0;
}
The result of this is:
28296 / 192 = 150912
Why isn't it 147? If I set a variable " int mult" equal to MULT, and use the variable in the expression (int y = x / mult) it works as expected.
#define tells the preprocessor to replace the code before compilation, so your line actually says:
int y = x / 6 * 32;
since * and / operators have the same precedence, and are evaluated from left to right, you get (x/6) * 32. The compiler would probably do this calculation for you since x is known to it.
Instead, use parenthesis when defining macros like this
Put a bracket around the macro:
#define MULT (FOO * BAR)
Now, you'll get 147.
The reason getting 150912 is that after macro expansion the expression is equivalent to:
y = 28296 / 6 * 32;
and hence it's evaluated as 28296/6 and then multiplied by32.
As #kevin points out, it's better to put brackets around FOO and BAR as well in general case to avoid surprises like this.
I have the simple following C code
#define Sqrt(A) A * A
int main(void) {
int A = 10;
int x = Sqrt(A+1);
return 0;
}
For some reason, when I used it like that, with A+1, I get x to be 21, which is probably 10+11.
My question is, how is the multiplication is being ignored?
If I switch the macro with the macro text, I get the right result which is 121.
Thanks.
First, your Sqrt is misnamed, should be Square (not square root)
Then, generate the preprocessed form (i.e. with gcc -C -E) and look inside it.
#define Sqr(A) A * A
int a = 10;
int x = Sqr(a+1);
where the last line is expanded as
int x = a+1 * a+1;
Which is parsed as
int x = a+(1*a)+1;
Moral of the story, always use extra parenthesis in macro definition, i.e.
#define Sqr(A) ((A)*(A))
Even with such a definition, Sqr(a++) is probably undefined behavior and at least is naughty.
So you want to avoid macros and actually, learn to use inline functions like
inline int square(int a) { return a*a; };
BTW, you will want to make it static inline not just inline (and put that in a header file)
'cos
#define Sqrt(A) A * A
makes
Sqrt(A+1);
translate to
A + 1 * A + 1
and A is 10
so you get
10 + 1 * 10 + 1
Now do the maths!
BTW sqrt has seems to say square root not squared!
You define the macro as A * A. So, Sqrt(A + 1) expands to A + 1 * A + 1, which is, due to operator precedence, equal to 2 * A + 1 - you've got 2 * 10 + 1 = 21.
That's why you should always parenthesize your macros and their arguments:
#define Sqrt(A) ((A) * (A))
By the way, why a macro? What if one day you write Sqrt(A++)? Then you can expect nasal demons. It would be safer to write an inline function instead (horribile dictu, a correctly named inline function):
static inline double square(double x)
{
return x * x;
}
Inside the macro, A is replaced with whatever was passed into the macro invocation. In this case, that is A+1. This means that the macro gets expanded to:
A+1 * A+1
Due to operator precedence, this is interpreted as A + 1*A + 1, or 10 + 10 + 1 = 21.
You should define the macro as #define Sqrt(A) ((A) * (A))
BODMAS rule buddy!! as the previous answers suggests. Multiplication takes place before your addition.
Your opertaion Sqrt(A+1) where A = 10 will evaulate to 10+1*10+1
10+10+1
21!!
Macros are substituted literally and then evaluated.
Since multiplication has more priority than addition, when you give A+1 to the macro it becomes 10 + 1 * 10 + 1 => 10 + 10 + 1 => 21
Likewise if you give A+2 ..... 10 + 2 * 10 + 2 => 10 + 20 + 2 => 32.
when you call x = MACRO_NAME(A+1); this statement is replace as x = A + 1 * A + 1
in c priority of multiplication is more than addition so it will be 1st executed 1*A which give as A, then A+A+1 will give you result as 21`enter code here`
i.e A+1*A+1
= A+A+1
= 21
for proper answer you need to write Macro as #define MACRO_NAME(A) (A) * (A) which give you result as
121