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