1

Here I have a simple algorithm that computes the square of a number by adding up all of the odd numbers equal to the inputted number, such that:

1 = 1 = 1-squared
1 + 3 = 4 = 2-squared
1 + 3 + 5 = 9 = 3-squared

and so forth. The algorithm is as follows:

int triangleSquare(int number) {
    int product = 0;
    int currentOdd = 1;

    while (number--) {
        product += currentOdd;
        currentOdd += 2;
    }

    return product;
}

My question is about the segment:

while (number--) { ... }

For some reason I get different results between while (--number) and while (number--), which I assume is because --number should decrement first before performing the while loop (and vice-versa for number--). My question is, why does it make a difference? Shouldn't the while loop always execute last, regardless of the increment order? I must be missing something obvious, but that seems very odd to me, almost as though number-- makes the conditional behave like a do {...} while() loop.

sircodesalot
  • 11,231
  • 8
  • 50
  • 83
  • Check this post: Your question seems similar to [this][1] post. [1]: http://stackoverflow.com/questions/1812990/incrementing-in-c-when-to-use-x-or-x –  Sep 12 '13 at 15:50
  • I understand the differences between the increments themselves. But I don't really understand why it would affect a while loop. It seems like no matter how you slice it, the increment should happen before the condition is tested, but obviously that doesn't seem to be the case. That's puzzling. – sircodesalot Sep 12 '13 at 15:55
  • 1
    --x decrements x and returns the decremented value. x-- decrements x and returns the *original* value – jcoder Sep 12 '13 at 16:01
  • `--number` is a predecrement, meaning that the value is decremented, and then the variable is retrieved, while `number--` is a postdecrement, meaning that the value is retrieved, and then the variable is decremented. So, because you are decrementing inside the while-loop's conditional, you're going to see this difference. – RobH Sep 12 '13 at 16:02
  • @sircodesalot Within the `while` loop, the value will be decremented, regardless. But the condition in the `while` is an expression. And the expression doesn't take into account when the actual decrementation occurs (which is unspecified), but the value of each element of the expression. And the _value_ of `number--` is the value of `number` before the decrementation. – James Kanze Sep 12 '13 at 16:06

3 Answers3

3

The two candidate loops could be written (are equivalent to):

while (number-- != 0)
while (--number != 0)

Consider what happens when number == 1 at loop entry:

  1. The value of number is compared to zero and then decremented; since 1 is not 0, the loop body is executed.
  2. The value of number is decremented and then compared to zero; since 0 is 0, the loop body is not executed.

That's the difference!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

while (number--) does the following:

  1. evaluate while (number)
  2. then number--

On the other hand while (--number) does this:

  1. calculate --number
  2. then evaluate while (number) with the new value

And that's the difference.

TobiMcNamobi
  • 4,687
  • 3
  • 33
  • 52
1

This is a horrible way to write code, but...

An expression has two characteristics: a return value, and side effects. The decrementation is the side effect; it is the same for --number and number--. The condition in the while, however, depends on the return value; --number returns the value after the decrementation; number-- the value before the decrementation. When the decrementation actually takes place on the variable is not really specified (for either): some time after the preceding sequence point and before the following one.

In other words: --number is the equivalent of:

int
decr( int& number )
{
    number -= 1;
    int results = number;
    return results;
}

and number-- is the equivalent of:

int
decr( int& number )
{
    int results = number;
    number -= 1;
    return return;
}

In both cases, you're testing the return value of the function.

James Kanze
  • 150,581
  • 18
  • 184
  • 329