tags:

views:

192

answers:

6

I am reading K&R book, on page 63 there is a line

while (--lim > 0 && (c=getchar()) != EOF && c != '\n')

where lim is int equal to 1000

My question, why is lim is not decreasing after consequential runs of while loop ? As I see it, --lim is equivalent to "lim = lim - 1"

===================================================================

Thanks for all the answers !

+5  A: 

--lim means "take one from the value of lim and use the result".

The alternative lim-- would be "use the value of lim and then take one away".

So if lim starts at 1000 the first time the loop executes it will have the value 999 before it is checked to see if it's greater than 0. If it were lim-- then the value that would be checked would be 1000, but it would still have the value of 999 at the end of the iteration through the loop. This is important at the start and end of the loop.

The MSDN as a page on this Prefix Increment and Decrement Operators

When the operator appears before its operand, the operand is incremented or decremented and its new value is the result of the expression.

ChrisF
Right! This is a very important distinction, when using --variable or varibale--. If you use it in a single line, there is no difference, but if you use it as a parameter somewhere, it makes huge differences!
Tseng
Mh good observation, was to much concentrated on the --lim part that I haven't looked at the rest
Tseng
@ChrisF: Yes it will. And it does.
David Titarenco
@Tseng - sorry, deleted comment! It was to the effect that if `getchar()` returned `EOF` or `\n` the loop would exit before `lim` hit 0.
ChrisF
+1  A: 

Are you sure?

#include <stdio.h>

int main()
{
        int lim = 10;
        while (--lim > 0 && printf("%d\n",lim));
}

ouput:

9
8
7
6
5
4
3
2
1
Let_Me_Be
A: 

--lim or lim-- is a short hand of lim = lim - 1, So maybe author want to use this syntax to better clarify!

Sadegh
No =/ they evaluate differently,... lim-- is NOT shorthand for lim = lim - 1, not unless used as a single monolithic statement.
Santiago Lezica
Oppps! yeah you're right man ;)
Sadegh
+1  A: 

Lim is decreasing, you probably made a mistake elsewhere. However, --lim is not quite equal to lim = lim - 1.

There are two operators to perform increment/decrement of a variable: pre-increment(or decrement), and post-increment(or decrement).

++x (pre-inc) and x++ (post-inc) both modify the value of x by +1. So what's the difference?

When you use x++ in an expression, the expression will consider x to have it's current value and after evaluating everything accordingly, increment that value by one. So...

int x = 5;
printf("%d", x++);

... will print out 5. HOWEVER, after the printf() line, the value of x will be 6.

Pre-increment works the other way round: the value of x it's first incremented, and then considered to evaluate the expression surrounding it. So...

int x = 5;
printf("%d", ++x);

... will print out 6 and, of course, the value of x will be 6 after that.

Of course, the same applies to the decrement operators.

Now, the assignment operation (x = x + 1) evaluates to the value assigned, after the assignment happened, so its behavior is actually similar to ++x, not x++.

Santiago Lezica
In summary, both `--lim` and `(lim = lim - 1)` decrement `lim` by one, and evaluate to the value after decrement. So how are they not equal?
Ben Voigt
Depends on the compiler. They are most probably equal, since compilers are more than smart enough to produce the same assembly code in both statements.
Santiago Lezica
A: 

Try to compile and run this code. It should be somewhat enlightening.

#include <stdio.h>

int main()
{
        int lim = 10;
        while (--lim > 0 && 1 > 32)
             printf("I should never get here\n");
        printf("%d\n",lim); // lim is now 9
}

Oh look, lim is now 9 even though I never actually entered the loop because 1 isn't greater than 32.

David Titarenco
A: 

Excluding David's example (where the initial test of 'c' causes the loop body to never be executed, and thus lim is not decremented), and the possibility that lim is initially less than or equal to 1 (in which case the getchar() would not be executed), the code is equivalent to the following:

c=getchar();
while (lim > 1 && c != EOF && c != '\n')
{
    lim = lim - 1;

    /* Original body of loop */

    c=getchar();
}

Both exceptions are rather unlikely and probably inconsequential, so you could use the above code if it's easier to understand.

reemrevnivek