Careful "for" Loops
Chris Torek
torek at elf.ee.lbl.gov
Wed Mar 20 05:45:19 AEST 1991
In article <MCDANIEL.91Mar19124111 at dolphin.adi.com> mcdaniel at adi.com
(Tim McDaniel) writes:
>Case a)
> semi-open intervals, like [low,high). low is in the range, but
> high is not. If high==0, the range extends from low through all
> higher memory. The problem is that high==0 is likely to prove a
> special case in iteration.
>Case b)
> closed intervals, like [low,high]. The range is inclusive: high is
> in the range. The problem is that upper bounds look ugly, like
> 0x01ffffff.
>... Zero-length ranges are a possibility.
Languages that do this sort of thing usually take closed intervals,
although there are ways to handle both.
For instance, the loop
for i := 1 to 300 do foo
(in Pascal) is usually generated as
if (1 <= 300) {
for (i = 1;; i++) {
foo;
if (i == 300)
break;
}
}
(equivalent C code). (Yes, it is OK to leave `i' unset; Pascal index
variables may not be examined after the loop ends, until they are set
to some other values.)
If there is a step, the loop must compute the terminator value (or
the number of iterations):
for i := 1 to 4 by 2
should compare for 3 (for ending) or compute a count of ((4-1)+1)/2
iterations. In some cases this can be done at compile time.
To do the same for half-open intervals, simply subtract one from the
end value (using unsigned arithemtic, if necessary, to avoid underflow)
and do the same. The loop
for i in [m..n) do foo;
can be `compiled' to
if (m < n) {
stop = n - 1;
for (i = 0;; i++) {
foo;
if (i == stop)
break;
}
}
Iteration count computations are identical except that instead of
((end - start) + 1) / incr
you simply use
(end - start) / incr
--
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA Domain: torek at ee.lbl.gov
More information about the Comp.lang.c
mailing list