4.2 CASE STUDY
PAGE 49
Any expressions are permitted as the initializing and updating components, a
range of possibilities that includes the empty expression. As an extreme, “for(;;);”
is a perfectly valid for loop, according to the rules of C. It does nothing before it
starts, then it performs no test (and in doing so, arrives at the value true), then it does
nothing and does the non-existent test again, and so on. Endlessly. Which brings us
back to the distinction made at the beginning of this chapter between treadmills and
spirals.
Loops should spiral, and move at each iteration towards a goal. When a controlled
variable is initialized, tested in the guard, and then updated, as has been the case in all
of the examples shown so far, positive progress along the path of the spiral is pretty
much guaranteed. But in the loop “for(i=0;i<10;)” there is no progress made,
and no spiral. It is a treadmill – which in computing is called an infinite loop – and
is an unwelcome addition to a program. In this simple case the error is reasonably
obvious, and almost certainly there is an i++ or similar statement missing. In more
complex settings, writing a loop that doesn’t make progress is an easy mistake to
make, and all programmers have agonized over the “why” of an endless loop at some
stage of their career.
So if you are faced with a program that appears to be “stuck” somewhere, the
very first thing to check is the loops – ensure that every loop makes progress, in
that whatever variable is being controlled in the loop moves towards the stopping
condition, as expressed in the guard.
In most for loops the controlled variable will appear in all of the
initialize, the guard, and the update parts.
The other reason why a program might get “stuck” is that it might be at a scanf
waiting for you to enter some data, without you realizing. That is why you should
always use printf to generate a prompt immediately prior to every scanf – to
minimize this possible confusion.
Sometimes a loop appears to unexpectedly execute fewer times t