Reputation: 69
I just came across this C question with the following code:
int fun();
int main()
{
for (fun(); fun(); fun())
printf("%d\n", fun());
return 0;
}
int fun()
{
int static n = 10;
return n--;
}
I expected the for
loop to evaluate to for(10;9;8)
and the printf
to print 7 (since we would be calling fun()
with n = 7
?) but it prints 8
. Why does this happen?
Upvotes: 1
Views: 154
Reputation: 311146
The return statement of the function:
int fun()
{
int static n=10;
return n--;
}
uses an expression with the postfix decrement operator. The value of the expression n--
is the value of the variable n
before its decrement.
From the C Standard (6.5.2 Postfix 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)....
3 The postfix -- operator is analogous to the postfix ++ operator, except that the value of the operand is decremented (that is, the value 1 of the appropriate type is subtracted from it).
So in the for loop
for (fun(); fun(); fun())
printf ("%d\n", fun());
you have the following.
The first expression fun()
of the for loop is evaluated only one time. After its call the variable n
within the function has the value 9
due to the postfix decrement operator.
Then the second expression fun()
that represents the condition of the for loop is evaluated. It returns the current value 9
of the variable n
and the variable is decremented and becomes equal to 8
Then within the body of the for loop the function is called again:
printf ("%d\n", fun());
This call of printf
outputs the current value of the variable n
equal to 8
and the variable is decremented. Now its value is 7
. Within the third expression of the for loop the function is called one more time and the value of the variable n
becomes equal to 6
.
After that the condition expression again is evaluated. The function returns the current value 6
of the variable n
and the variable is decremented. Its value now is equal to 5
.
In the call of printf
this value 5
is outputted while the value of the variable n
itself becomes equal to 4. After the evaluation of the third expression of the for loop the variable n
becomes equal to 3. This value is returned by the function in the condition of the for loop and the variable itself becomes equal to 2. And this value is outputted in the call of printf.
In the call of printf
this value 2
is outputted and variable n
is decremented and is equal to 1
.
Then due to the third expression of the loop the variable n
is decremented and becomes equal to 0
. This value is returned by the function call in the condition expression. So the loop stops its iteration. At the same time the value of the static variable n
within the function becomes equal to -1
.
So the for loops outputs the following values:
8
5
2
If you will add one more call of printf
after the for loop:
for (fun(); fun(); fun())
printf ("%d\n", fun());
printf ("%d\n", fun());
then the output will be:
8
5
2
-1
Upvotes: 3
Reputation: 145307
Your interpretation would be correct if the for
loop had an empty body such as:
for (fun(); fun(); fun());
The fact that printf ("%d\n", fun());
is not indented suggests you meant or at least interpreted the code this way.
Bad indentation can be very misleading, and this interview question is a trick question indented to test your sharp eyes. A for
statement without a block or an indented statement should immediately attract your attention. The code should be reindented as:
int fun();
int main()
{
for (fun(); fun(); fun())
printf("%d\n", fun());
return 0;
}
int fun()
{
int static n = 10;
return n--;
}
Function fun()
returns n--
: the value returned is the original value of n
, which is then decremented. So successive calls to fun()
return decreasing numbers, starting from 10
: the first one (10
) is ignored, the second one (9
) is tested as the for
condition and is not 0, the next one (8
) is printed, the next one (7
) is ignored, then the condition is tested again with the value 6
...
The output is 8
, 5
, 2
, and the next test is 0
so the loop exits and the main
function returns 0
to the operating system.
Note however that calling printf
without a proper declaration in scope has undefined behavior because the prototype inferred by the compiler (is any) int prinf(const char *, int)
is different and incompatible with its actual implementation.
If <stdio.h>
is not included prior to the call and a standard prototype int printf(const char *fmt, ...);
is not present before the beginning of the posted code, the ultimate answer to this interview question is:
The code has undefined behavior, it probably outputs this but with no guarantee:
8
5
2
Upvotes: 1
Reputation: 142
The answer is correct. In initialization n becomes 10
.
condition1- n = 9
Then
print1-8printed
update-7
condition2-6
print2 - 5 printed
and so on
The first answer was edited since on checking it was wrong.
Note:-the answer was to convert postfix to prefix which broke the code on testing
Update:- The reason prefix increment
did not work was because condition was not checked with 0 but with -1
and 2
. There was no checking with 0
. Hence an infinite loop
Upvotes: 1
Reputation: 26385
Expecting for(10;9;8)
is wrong.
The order of operations for a for
loop is:
for (<0>; <1>; <3>) {
<2>;
}
assuming <1> is truthy, <2> does not contain statements that end the loop, and where after <3> the construct repeats from <1>.
Thus you have for (10; 9; 7) { 8; }
.
Then for (_; 6; 4) { 5; }
, and so on.
Upvotes: 5