This question already has answers here:
Why is "i" variable getting incremented twice in my program?
(8 answers)
Closed 7 years ago.
Why outputs of i and j in the following two printf()s are different?
#include <cstdio>
#define MAX(x,y) (x)>(y)?(x):(y)
int main()
{
int i=10,j=5,k=0;
k==MAX(i++,++j);
printf("%d %d %d\n",i,j,k);
i=10,j=5,k=0;
k=MAX(i++,++j);
printf("%d %d %d\n",i,j,k);
return 0;
}
I think only k should differ, but it is showing different output for all, i, j and k, in printf() statement. What is the reason?
Output :
11 7 0
12 6 11
k==MAX(i++,++j); is translated to:
k==(i++) > (++j) ? (i++) : (++j);
/* 2 1 3 : Precedance */
In your case i = 10 and j = 5, so the comparision would be 10 v/s 6 which would be true or 1 with side effect i becomes 11 and j becomes 6. (Recall that: Macros are not functions)
As k = 0 and not equal to 1, k==(i++) > (++j) would be false and ++j would be executed. Causing j to be incremented to 7.
In latter case, there is no modification to the value of variables.
When can I expect same output in both case?
Even if you change the macro with a function, your arguments have the side effects, which would cause the output 11 6 for i j, so you are changing the variables using ++ operator, don't expect both statements to have the same values.
i++ and ++j both increment i and j, so you change their values before printing.
You have side-effects.
MAX(i++,++j)
is expanded to
(i++)>(j++)?(i++):(j++)
And i is modified twice in the macro call.
Moreover, you have to add parens to your macro definition:
#define MAX(x,y) ((x)>(y)?(x):(y))
Let's analyse the output from first printf()
Assuming you meant = instead of == in your code,
k==MAX(i++,++j);
gets translated to
k = (i++) > (++j) ? (i++): (++j)
which gets evaluated changing all the values of i, j and k.
Even if you meant ==, as mentioned in the answer by Mr. Mohit Jain, you'll face similar issue with precedence.
Have a look at operator precedence for better understanding.
Let's analyse the output from second printf()
In the second printf() statement, you're re-setting the values of i, j, k and not using the MACRO. So, those values will get printed. Simple.
So, TL;DR, before first printf(), the MACRO changes all the three values for i, j, k. So, your output for first and second printf() differs for all the three variable values.
FWIW, if you meant the MACRO to behave as a ternary conditional expression , you need to change your MACRO definition to
#define MAX(x,y) ( (x)>(y) ? (x) : (y) )
To avoid issues with operator precedence after MACRO expansion.
The macro is a red herring. OP did not ask about k but "Why output of i and j in following two printf are different?" The answer is because i and j have been modified between setting their values and printing, in the first case, but not in the second case.
Related
The semicolon has been added after the first while loop, but why is the value of the i variable 3 here, where j is 2?
#include<stdio.h>
int main()
{
int i=1;
while(i++<=1);
printf("%d",i);
int j=1;
while(j++<=1)
printf("%d",j);
return 0;
}
Both while loops run once (and once only); the difference is that, in the second case (the j loop) you are printing the 'control variable' inside the loop but, for the first case, you are printing it after the loop condition has evaluated to false. Also note that, in the first case, the semicolon immediately following the while statement defines the body of that loop as empty1.
Let's break down the first loop into steps:
On the first test of the condition, i++ evaluates to 1 and then i is incremented – so the loop runs.
On the second test, i++ evaluates to 2 (so the loop doesn't run) but i is still (post-)incremented, leaving it with the value of 3 (as shown in the output).
The same thing happens with j in the second loop but, in that case, as previously mentioned, you are displaying the value in the body of the loop (on its only run), so you see the value after the first (post-)increment.
As noted in the comments, if you add another printf("%d", j); after the body of the loop (which, in that case, consists of a single statement), you will see that j, too, has the value 3 when that loop has finished.
1 More precisely, the semicolon (on its own) defines a null statement, which forms the body of the while loop.
It is often helpful to clarify such 'null loops' by putting the semicolon on a line by itself (some compilers, with full warnings or static analysis enabled, may even suggest you do this):
#include<stdio.h>
int main()
{
int i = 1;
while (i++ <= 1)
; // Body of loop - Null Statement
printf("%d", i); // Loop has finished
int j = 1;
while (j++ <= 1)
printf("%d", j); // Body of loop
// Loop has finished
return 0;
}
For starters let;s consider how the postfix increment operator works. From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it).
Now consider this while loop
int i=1;
while(i++<=1);
In the first iteration of the loop the value of the expression i++ as the value of its operand that is 1. So the loop will iterate a second time, Due to applying the side effect to the variable i it will be equal already to 2 when the expression i++<=1 will evaluate the second time.
Now the value of i is equal to 2 and is greater than 1. so the loop will be interrupted. Again due to applying the side effect of the postfix increment operator to the variable i it will be equal to 3. This value is outputted in the following call of printf.
In simplest terms,
consider three things for each iteration of first while loop:
first iteration:
int i = 1;//initialization
while(i++<=1); //1. i evaluated as 1,
//2. loop condition is true causing loop to iterate again.
//3. ...but not before ++ causes i==2.
second iteration:
while(i++<=1); //1. i evaluated as 2,
//2. loop condition is false causing loop to eventually exit
//3. ...but not before ++ causes i==3.
printf is not included in the while loop (because of the semicolon) but
when program flow finally reaches printf("%d",i); the value of i is output as 3
In the second loop, because printf is included in the while construct, it will output the value of j for each iteration. For the same reasons as in loop one, it will also iterate only twice, and its values at time of output will be 2 & 3.
Using a debugger to set break points, and a watch on i, you can step through code such as this to see the sequence of these effects as they happen.
For explanation porpouses look at this example:
int main()
{
int i=1;
while(i++<=1)
printf("%d",i);
printf("%d",i);
}
The Output is:
2
3
Ok let's dive into the programm procedure:
Declaring i (i = 1)
while checking Condition and it's true because i++ returns 1(old Value). That's because the ++ are after the i. If you would code it like this ++i than it returns 2(new Value) (i = 2)
execute printf (i = 2)
while checking Condition and it's false because i++ returns 2 and 2 is not <= 1 (i = 3)
execute printf (i = 3)
Do you understand?
If it solved your thoughts jumble ;) mark it as answer.
You've got many answers already so I won't try to explain it in words but with an illustration in code. I've added two functions:
One that acts like a prefix increment operator (++i)
One that acts like a postfix increment operator (i++)
I'm only using the postfix version in the program though. I've added logging to the function so you can see how it works.
#include <stdio.h>
// this acts as if you put ++ before the variable
int preinc(int* p) {
++*p;
return *p;
}
// this acts as if you put ++ after the variable
int postinc(int* p) {
int rv = *p;
++*p;
printf("returning %d but incremented to %d\n", rv, *p);
return rv;
}
int main() {
int i=1;
while(postinc(&i) <= 1);
printf("end result: %d\n---\n", i);
int j=1;
while(postinc(&j) <= 1)
printf("in loop: %d\n", j);
printf("end result: %d\n", j);
}
Output:
returning 1 but incremented to 2
returning 2 but incremented to 3
end result: 3
---
returning 1 but incremented to 2
in loop: 2
returning 2 but incremented to 3
end result: 3
If you add the semicolon in the end of the while you will take: i = 3 and j = 3(IN THE OUTPUT).
If you add the semicolon only in the end of the printf and not to the while you will take i = 2 and j = 2(IN THE OUTPUT), but in the end you will, also, have the values
i = 3 and j = 3.
This happens because the "i" variable is incremented only after the first iteration of the loop, in which the empty statement (terminated by the semicolon) is evaluated.
that is why it is highly recommended to do "++i" rather than "i++", because then the incrementation is performed prior to the evaluation.
if you flip it here, you will see that i will be equal to 2 as well, regardless of the presence of the semicolon
This question already has answers here:
What is the difference between ++i and i++?
(20 answers)
Closed 4 years ago.
I was solving some multiple choice C codes from a book. Two of the questions involve pre decrementing, post decrementing a char variable initialised at 0. The output for both these is very different. I dont understand whats going on there.
Code 1
char i=0;
do
{
printf("%d ",i);
}while(i--);
return 0;
The output for this snippet is 0.
Code 2
char i=0;
do
{
printf("%d ",i);
}while(--i);
return 0;
The output is for this one is
0,-1,-2,.....-128,127,126,......1 .
Can anyone explain why this is happening?
At both code while loop checking i==0 or not. If i!=0it will keep going on.
At first code value of i initially 0. So after printing 0 it checks i==0 or not. if i==0 it will break the loop or keep going on by decrementing i. So in code 1 post decrementing used. check value first then decrements the value.
At second code value of i initially 0. So after printing 0 it decrements i then it checks if i==0 or not. it is pre decrement. decrement value first then check.
Here, i is char which size is 1 byte and range -128 to 127. So after decrementing value 0 to -1 it keep decrementing until it goes to 0 and exit the loop by printing 0,-1,...,-128,127...1 .
Code 1
char i=0;
do
{
printf("%d ",i); // print o
}while(i--); //check i = 0, means false, loop ends, then increment i
return 0;
Code 2
char i=0;
do
{
printf("%d ",i); //print 0
}while(--i); //decrement i, check i=-1, means true, next cycle, loop until i = 0 which means false
return 0;
Both i-- and --i are expressions. An expression is (part of) a statement that can yield a value. As per definition, the pre-increment version increments first, then yields the value. For the post-increment version it is the other way round.
This is completely independent of whether the expression is used in a while statement or elsewhere. However, when using such expressions, you need to be aware of operator precendence.
Initial value of i is 0.
In Code 1, first while check happens in which the value of i (= 0) is used and then i is decremented because it is postfix decrement. So it exits while after printing 0.
In Code 2, because it is prefix decrement, i is decremented first and its value (= -1) is used when the while check is performed. Here it exits after printing the entire range of values a signed char can hold because it becomes 0 at the end only.
EDIT: This question is not duplicate as the behavior is not undefined in this case.
Why does the below program print the output as 231 in first line?
I have two doubts regarding this:
As I am doing postfix increment the value of x shouldn't have been increased before the I call max function. So the output should have been 1 in the first place instead of 2 according to me. What am I missing?
#define prn(a) printf("%d",a)
#define print(a,b,c) prn(a), prn(b), prn(c)
#define max(a,b) (a<b)? b:a
main()
{
int x=1, y=1;
print(max(x++,y),x,y);
printf("\n");
print(max(x++,y),x,y);
}
Output:
231
451
The postfix operation occurs after execution of the statement? Consider the example below.
int main()
{
int x = 0, y = 1;
int a = x++ /*x is incremented hereafter?*/+ y; // line 1
/* Or x is incremented now after execution of above line?*/ // line 2
int b = 0;
}
let me take this line
print(max(x++,y),x,y);
One important point to note is that the C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be inclusion of header file, macro expansions etc.
All preprocessing directives begins with a # symbol. For example,
#define PI 3.14
tells the compiler to replace the value PI with 3.14 where ever it sees.
c source code->preprocessor->compiler
therefore print(max(x++,y),x,y) is expanded in macro to
1. prn((x++<y) ? y:x++), prn(x), prn(y)
2. printf("%d",(x++<y)? y:x++), printf("%d",x), printf("%d",y);.
here it gets processed you can check two things carefully here
while checking
x++<y ,the x++ value is 1
then after that the x value becomes 2
so 2 is printed
and then while printing also we wrote x++ that means here x++ VALUE IS 2 but
after that x value is 3
so 3 is printed and it follows y as 1
that 's how it works
2.TO give you a great intuition on preincrement and post increment
let me take an example
int x=2;//value of x is 2
x++;//here x++ value is 2
after this line execution x value changed to 3
++x//here x++ value is 4 and also x value is 4.
This question already has answers here:
C comma operator
(4 answers)
Closed 5 years ago.
Whats the difference between:
int i;
for( i=0;i<5 && i<3;i++)
{
printf("stackoverflow.com");
}
and
int i;
for( i=0;i<5 , i<3;i++)
{
printf("stackoverflow.com");
}
I mean use of && instead of ','
Regards
In the second code block, only i < 3 is actually used to evaluate whether the loop should exit. The i < 5 expression is evaluated, but its value is discarded. See the comma operator for more info.
There is functionally no difference between your examples because i < 3 is the limiting expression and appears second. Both loops will exit when i reaches 3. However, if you switched the terms so that you have i < 3, i < 5, then the second kicks out when it reaches 5 because only the value of i < 5 is considered.
In this case they will do exactly the same.
The thing that differs is that in the first case i<3 will not be evaluated every time. A statement on the form A && B will only execute B if the return value of A is true. The reason is that the logical value of && is true if both operands are true. If one of them are false, the whole expression is false, so if the left operand evaluates to false, there's no need to evaluate the right operand.
The comma operator on the other hand evaluates both operands, but the result of the left operand is discarded.
When using the comma operator , in a statement like the:
( <expression1>, <expression2> )
the <expression1> is evaluated and discarded, then the <expression2> is evaluated and its value is returned. In summary the right most expression is evaluated and its value returned. Other expressions are evaluated and discarded. So your statement of:
for(i=0; i<5 , i<3; i++)
is equivalent to:
for(i=0; i<3; i++)
As for the first statement, this expression:
(i<5 && i<3)
is a simple AND boolean evaluation. A funny one because it is enough to say:
(i<3)
Long story short, who ever made this example probably expects you to say "both conditions evaluate to second expression".
#include "stdafx.h"
#include<stdio.h>
#define PR(x) printf("%d\t",(int)(x));
#define PRINT(a,b,c) PR(a) PR(b) PR(c)
#define MAX(a,b) (a<b?b:a)
int main()
{
int x=1,y=2;
//PR(MAX(x++,y));
PRINT(MAX(x++,y),x,y); //2,2,2
PRINT(MAX(x++,y),x,y); //2,3,2
return 0;
}
x is 1 so the 3 values to be passed as arguments in PRINT is 2 2 2.
Then in the second PRINT the values that will be passed is 2 3 2. So the output should be 2 2 2 2 3 2. But this program outputs as 2 2 2 3 4 2.
Your MAX macro is bad. It evaluates one of its arguments twice.
MAX(x++,y)
expands to:
(x++ < y ? y : x++)
^^^
So x is incremented twice if it started out smaller than y.
There is no undefined behavior in that code because there is a sequence point between the evaluation of the first part of the ternary operator and the part that is selected. The whole PRINT expression expands to:
printf("%d\t", (x++ < y ? y : x++));
printf("%d\t", (x));
printf("%d\t", (y));
Which is all fine. This does not mean you should be using such macros. Use simple functions, and let the compiler do its job of type-checking and inlining what it thinks is best.
Your macros have several problems:
Never hide a ; inside a macro but have it behave like an ordinary
statement
Don't write macros that evaluate their arguments multiple times
always put parentheses around macro parameters such that you know the
precedence of all operators.
Your MAX(x++,y) call translates to (x++<y?y:x++) and results in double modification of x during the first call.
PRINT((MAX(x++,y),x,y) -> PR(MAX(x++,y)) PR(x) PR(y) -> PR(x++
x = 1, y = 2
Does PR(2 since 1<2) and increments x to 2
Then PR(2) PR(2) - Hence output 2 2 2
Next PR(MAX(x++ (i.e.2) < 2 - false) ? 2 : x++ (i.e use incremented value of x from condition (3) then output 3 and increment x to 4) - hence x gets incremented twice