bharath2438
bharath2438

Reputation: 69

Why does the following code print 8,5,2 instead of 7,4,1?

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

Answers (4)

Vlad from Moscow
Vlad from Moscow

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

chqrlie
chqrlie

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

JustaNobody
JustaNobody

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

Oka
Oka

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

Related Questions