0

What does for (; --i >= 0; ) mean in C?

How is the counter getting decremented and how is it different from for ( ; i >= 0; --i)?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vishal Singh
  • 73
  • 1
  • 3
  • 11

8 Answers8

3

These constructs are formally equivalent to

while (--i >= 0)
{
  Body;
}

and

while (i >= 0)
{
  Body;

  --i;
}

Do you better see the difference?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3

They are very similar, but not the same! First you have to understand how a for loop in C gets executed:

As an example:

      1      2, 5  4
      |      |     |
      v      v     v
for(i = 0; i < 5; i++) {
    // Do something <-- 3
}

As you can see 2, 3, 4, 5 is a loop until the condition is false.


Now you should clearly see how the for loop gets executed. The difference now is that in your first example:

int i = 5;
for ( ; --i >= 0; )
    printf("%d\n", i);

The output would be:

4
3
2
1
0

Because after the first check of the condition (Point 2), it executes the code block of the for statement and i already gets decremented.

In your second example:

int i = 5;
for( ; i>=0; --i)
    printf("%d\n", i);

The output would be:

5 // See here the difference
4
3
2
1
0

Here you get the difference, because it gets decremented in Point 4, so the first time it runs with the value 5.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rizier123
  • 58,877
  • 16
  • 101
  • 156
1

In general, we can convert any for loop or while loop into a set of mostly linear statements with a goto. Doing this may be helpful to compare the code.

Case 1

### for (; --i >= 0; ) { statements; }
  ;                            // Initializer statement
start:
  bool condition = (--i >= 0); // Conditional
  if (condition) {             // If true, we execute the body as so:
    statements;                // The statements inside the loop
    ;                          // Empty increment statement
    goto start                 // Go to the top of the loop.
  }

Case 2

### for( ; i>=0; --i) { statements; }
  ;                            // Initializer statement
start:
  bool condition = (i >= 0);   // Conditional
  if (condition) {             // If true, we execute the body as so:
    statements;                // The statements inside the loop
    --i;                       // Increment statement
    goto start;                // Go to the top of the loop.
  }

Let's compare the "simpler" code from those two cases.

In the first case, we decrement i for the first time before each loop body. In the second case, we decrement i after each loop body.

The easiest way to see that is to consider what happens when you enter this loop when i == 0. In the first case, after this block of code, you would have a resulting value of i == -1. In the second case, i wouldn't have changed (that is, i == 0), because we never reached the increment statement.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
0

for (; --i >= 0; ) works like this:

Say if you have i as 10, it will decrement the i value and will compare 9 >= 0 and so on.

So the output would be like 9, 8... till 0.

While the loop for( ; i>=0;--i) would first go to 10, then decrement the value and then it would check i>=0. So the output would be 10, 9, 8... till 0.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SMA
  • 36,381
  • 8
  • 49
  • 73
0

The first one decrements i and then checks the condition.

The second one checks the condition first and if true, decrements i after the loop body has been executed.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
0

The three parameters (initialization, condition and increment) in for are optional (but they still requires the semicolon ;). So, you can safely write for(;;) and it's the same as while(1). So, expressions like

for(; x > y; x++) { ... }

for(;1;x++) { if(x > y) break;

for(;;) { if(x++ > y) break;

for(;x++ > y;) { ... }

Are valid and equivalent. In this, the increment occurs in the conditional parameters, just like in your code example.

Jack
  • 16,276
  • 55
  • 159
  • 284
0

Well, it is the same as saying for( i=0 or some value; --i <= 0 ; do nothing){} and --i is an predecrement operator.

That means when this piece of code, i.e., --i, is being read, the value of i will decrease by 1 at the same moment.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

There are three main components in a for loop.

Initialization, condition, and afterthought.

Initialization happens once at the start of the entire statement. Condition happens before every cycle. Afterthought comes after every cycle. Consider i starts at 2:

for (; --i >= 0; )

Initialization: i = 2
Condition: i = 1
Afterthought: i = 1
Condition: i = 0
Afterthought: i = 0
Condition: i = -1
Exit

In the other case

for( ; i>=0; --i)
Initialization: i = 2
Condition: i = 2
Afterthought: i = 1
Condition: i = 1
Afterthought: i = 0
Condition: i = 0
Afterthought: i = -1
Condition: i = -1
Exit

You can see that the second version actually lasts one cycle longer!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
flakes
  • 21,558
  • 8
  • 41
  • 88