Whats the logic behind the output [duplicate] - c

I was just going through certain code which are frequently asked in interviews. I came up with certain questions, 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();
}
The 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!!?

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

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.

i=4/square(4);
expands to
i=4/4*4;
which equivalent to
i=(4/4)*4;

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;

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.

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

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.

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

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

Because of operator precedence in the expression after the preprocessor - you'll need to write
#define square(x) (x*x)

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.

Related

not understanding how the output is generated

i expect the output (or value of silly) to be 36. but what i get is 14. this is fixed when i add parentheses: #define THING (4+2).
but i still want to know what is happening when there are no parentheses and why im getting an output of 14
.
the following is my code:
#include <stdio.h>
#include <stdlib.h>
#define THING 4+2
int main(void)
{
int silly = THING * THING;
printf("%d", silly);
return EXIT_SUCCESS;
}
THING*THING = 4+2*4+2 = 4+(2*4)+2 // because of higher precedence of * than +
= 4+8+2 = 14.
Do remember that MACROs are exactly replaced(substituted) into the code.
The macro is literally inserted in place of THING.
THING * THING is 4+2 * 4+2 is 4 + (2 * 4) + 2 which is 14.
If you want the result to be 36 than you need to define your macro wrapped in parenthesis:
#define THING (4 + 2)
Because macros are (almost) the same as text replacement. int silly = THING * THING; is converted by the preprocessor to int silly = 4+2 * 4+2;, and order of operations means that's processed as 4 + (2 * 4) + 2, not (4 + 2) * (4+ 2).
You need parentheses because order of operations is interfering. Macros just replace text, and so without parentheses, the operations are not being evaluated in the order expected.
THING * THING ----> 4 + 2 * 4 + 2 = 14
So, once you use parentheses, this fixes it because it becomes:
THING * THING ----> (4 + 2) * (4 + 2) = 36
This is explained in this preprocessor tutorial.

Macro function to behave like for loop

Consider the following code i managed to write:
#include <stdio.h>
#define FOR(A, B, C) for(A; B; C++)
int main()
{
FOR(i=0, i<10, i)
printf("%i", i);
return 1;
}
The output is:
0123456789
If i do FOR(i=5, i<10, i)
then respectively the output is 56789
My questions are is that legal? Will it cause any errors in different cases? Does it works exactly like a for loop?
Yes it's a "legal" macro, but no, it does not work like a real for loop.
Your macro won't handle this:
int a, b;
for(a = 0, b = 4711; a < b; ++a);
for instance, since you can't distinguish the , used to build a longer initializing expression to the one used to separate the expressions that make up the parts:
FOR(a = 0, b = 0, a < b, ++a);
will break, since it looks like a call with 4 arguments instead of 3.
A macro is just copied everywhere the preprocessor sees you using the macro keyword. It just copies the text, nothing more.
To elaborate on that a bit more, consider this example:
#define MY_MACRO a
int MY_MACRO = 5;
When the preprocessor comes along it will take the above and change it to:
int a = 5;
and then the compiler will come along and compile it like normal C/C++ code.
When you add arguments to your macro, they are just substituted in place within your macro. This can be a problem, consider the following two macros:
#define BAD_MACRO(a, b) a*b
#define GOOD_MACRO(a, b) (a)*(b)
They look almost the same, but consider the following:
int k = BAD_MACRO(2, 3); // k = 2*3 = 6
int j = GOOD_MACRO(2, 3); // j = 2*3 = 6
int m = BAD_MACRO(2+1, 3); // m = 2+1*3 = 5
int n = GOOD_MACRO(2+1, 3); // n = (2+1)*3 = 9
Although note that neither of these macros are good or bad, they just don't have the same behaviour as a typical function.

Behaviour of macro changes when used with parenthesis

Why is max(0,1) behaving differently than max(1,0) in this program?
#define max(a,b) ((a)>(b))?(a):(b)
int main()
{
printf("max(0,1) = %d \n",max(0,1));
printf("max(0,1)+1 = %d \n",max(0,1)+1);
printf("max(0,1)+2 = %d \n",max(0,1)+2);
printf("max(1,0) = %d \n",max(1,0));
printf("max(1,0)+1 = %d \n",(max(1,0)+1));
printf("max(1,0)+2 = %d \n",(max(1,0)+2));
return 0;
}
output:
max(0,1) = 1
max(0,1)+1 = 2
max(0,1)+2 = 3
max(0,1) = 1
max(1,0)+1= 1
max(1,0)+2= 1
And why do these behave well if one extra parenthesis is used?
#define max(a,b) (((a)>(b))?(a):(b))
Because the ?: conditional operator has lower operator precedence than the binary + operator.
Thus max(1,0)+1 gets interpreted as 1>0?1:(0+1)
Perfect example of why you shouldn't use function-like macros.
The ternary operator ? : has a very low operator precedence: much lower than addition. Therefore you need to put the ternary in brackets so, when it's used to compute a maximum, the final addition, if any, is computed after the ternary.
You can always resort to unpicking a macro:
max(1,0) + 1 unpicks, with your first definition of max to (1) > (0) ? (1) : (0) + 1 which is, of course, 1. With the second definition it is ((1) > (0) ? (1) : (0)) + 1 which is 2.
After the macro expansion #define max(a,b) ((a)>(b))?(a):(b), your statements
printf("max(0,1)+1 = %d \n",max(0,1)+1);
printf("max(1,0)+1 = %d \n",(max(1,0)+1));
looks like
printf("max(0,1)+1 = %d \n",0 > 1 ? 0: (1+1));
printf("max(1,0)+1 = %d \n",(1 > 0 ? 1: (0+1)));

Unexpected output in c [duplicate]

This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 4 years ago.
I am new to c language. I just wanted to know why is my macro not working properly. It is giving me output as 13 where as my expected output is 24.?
#include<stdio.h>
#define mult(a,b) a*b
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
mult(x+2,y-1) expands to x +2 * y -1 that is equals to 4 + 2 * 5 -1 gives output: 13.
You might be expecting answer (4 + 2) * (5 -1) = 6 * 4 = 24. To make it expand like this you should write parenthesize macro as #H2Co3 also suggesting:
#define mult(a,b) ((a)*(b))
Read aslo: So, what's wrong with using macros? by Bjarne Stroustrup.
This is because C macros are simple textual substitutions, the macro writer must be sure to insert parentheses around every macro variable when it is substituted, and around the macro expansion itself, to prevent the resulting expansion from taking on new meanings.
If you observe your program: mult(a, b) is defined as a * b
mult(x + 2, y - 1) = x + 2 * y - 1 = 4 + 2 * 5 - 1 = 4 + 10 - 1 = 13
The Correct way would be:
mult(a, b) ((a) * (b))
Use parentheses in the macro definition
#include<stdio.h>
#define mult(a,b) ((a)*(b))
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
This is because different arithmetic operators have different precedence levels. Hence always use parentheses while defining the macro.
Because it replaces the arguments literally:
mult(x+2,y-1) --> mult(4+2,5-1) --> 4 + 2*5 - 1 --> 13
Try changing the define to:
#define mult(a,b) (a)*(b)
In this case the result after pre-processing is this:
int main()
{
int x=4,y=5;
printf("%d",(x+2)*(y-1));
return 0;
}
This will solve the problem but it's still not the best way to do it.
#define mult(a,b) ((a)*(b))
This version is considered as good practice because in other types of situation the first one would fail. See the bellow example:
#include<stdio.h>
#define add(a,b) (a)+(b)
int main()
{
int x=4,y=5;
printf("%d",add(x+2,y-1)*add(x+2,y-1));
return 0;
}
In this case it would give an incorrect answer because it is translated by the pre-processor to the fallowing:
int main()
{
int x=4,y=5;
printf("%d",(x+2)+(y-1)*(x+2)+(y-1));
return 0;
}
printing 34 instead of 100.
For the ((a)+(b)) version it would translate to:
int main()
{
int x=4,y=5;
printf("%d",((x+2)+(y-1))*((x+2)+(y-1)));
return 0;
}
giving a correct answer.

How does the preprocessor work in C?

Why is the answer for the below code 16? Can anybody explain the working of this program?
#define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
If we write the same code like below, then the answer is 4:
//the ans is 4 why?
#include<stdio.h>
#include<conio.h>
#define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
The preprocessor just replaces the text, exactly as written.
So, the macro call SQUARE(2) becomes literally 2*2.
In your case, that means the whole expression becomes 16/2*2, which because of C's precedence rules evaluates to (16/2)*2, i.e. 16.
Macros should always be enclosed in parenthesis, and have each argument enclosed as well.
If we do that, we get:
#define SQUARE(n) ((n) * (n))
which replaces to 16/((2) * (2)), which evaluates as 16/4, i.e. 4.
The parens around each argument makes things like SQUARE(1+1) work as expected, without them a call such as 16/SQUARE(1+1) would become 16/(1+1*1+1) which is 16/3, i.e. not at all what you'd want.
Order of operations. Your expression is evaluating to:
j = 16 / 2 * 2
which equals 16. Make it:
#define SQUARE(n) (n*n)
which will force the square to be evaluated first.
You need to define your macro with insulating parentheses, like so:
#define SQUARE(n) ((n)*(n))
Otherwise
j = 16/SQUARE(2);
expands to
j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2
When what you want is
j = 16 / (2 * 2);
1. When using macros that are to be used as expressions, you should parenthesise the whole macro body.
This prevents erroneous expansions like:
#define SQUARE(x) x*x
-SQUARE(5,5)
// becomes -5 * 5
2. If the macro arguments are expreessions, you should parenthesise them too.
This prevents a different type of problems:
#define SQUARE(x) x*x
SQUARE(5+2)
// becomes 5 + 2*5 + 2
Hence the correct way is to write it like this:
#define square(n) ((n)*(n))
-SQUARE(5+2)
// becomes -((5+2)*(5+2))
Using macros as functions is discouraged though (guess why), so use a function instead. For instance:
inline double square(n) { return n*n; }
The Expansion of macro will be like:
j = 16/SQUARE(2);
j = 16/2*2;
Which is equal to : j = (16/2)*2; Means j = 16;
and :
j = 16/(SQUARE(2));
j = 16/(2*2);
Which is equal to : j = 16/4; Means j = 4;
Because the macro will be expanded as:
j = 16/2*2;
The pre-compiler does not do any processing on the expansion. It places the expanded macro in your code as it is. Since you have not parenthesized the replacement text it wont do it for you in the main code as well. Make it :
#define SQUARE(n) ((n)*(n))
The first example is evaluated as:
16 / 2 * 2
(16 / 2) * 2
8 * 2
16
The second example is evaluated as:
16 / (2 * 2)
16 / 4
4
Add parenthesis to you preprocessor statement to control the order of operations:
#define SQUARE(n) ((n)*(n))
The outer parenthesis in ((n)*(n)) ensure that n is squared before any outside operation is performed. The inner parenthesis (n) ensure that n is correctly evaluated in cases where you pass an expression to SQUARE like so:
16 / SQUARE(2 * 2)
16 / ((2 * 2)*(2 * 2))
16 / (4 * 4)
16 / 16
1
you'll get
j =16/2*2; // (16 / 2) * 2 = 16
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("\n j=%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("\n j=%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

Resources