Consider `for (size_t i = 0; i < 5; ++i) { /* work */ }`. The condition `i < 5` is checked before each execution of the body. Starting at zero and incrementing after each iteration, `i` takes the values 0 through 4; the loop stops when the condition is false. A stopping criterion may therefore be written as a condition for *continuing*: here, stop when `i` is no longer less than 5. section 2.4.1
C evaluates a numerical condition as false when its value is zero and true when it is nonzero. Thus `for (size_t i = 10; i; --i)` stops when `i` reaches zero; it needs no explicit `i != 0`. An `if` condition uses the same truth rule, but selects whether a block runs once rather than whether iteration continues. section 3.1 section 3.2
TAKEAWAY: place the test where it matches the work being controlled.
- Use `for` for iteration over a domain: initialize once, test before each body execution, then update after each iteration. Define the iteration variable in the loop’s initial part. section 2.4.1
- Use `while` when the continuation test belongs before the body; use `do ... while` when it belongs after the body. The latter executes its body before its first test. section 3.2
- When the stopping test is best made inside the body, test it with `if` and leave with `break`. An unconditional `while (true)` or `for (;;)` needs such an exit in the shown approximation examples. section 3.2
- Check a recursive function’s termination condition first. Without that check, repeated calls can exhaust system resources. section 7.3
Stop when an approximation is close enough
For an approximation `x` to `1/a`, `fabs(1.0 - a*x) < ε` tests whether the product is close enough to 1. A `while` loop can continue while the error is at least `ε`; alternatively, an `if` inside the loop can `break` when the error is below `ε`. The update must make progress toward the chosen threshold for either form to terminate. section 3.2
while (true) {
double prod = a*x;
if (fabs(1.0 - prod) < ε) { // Stops if close enough
break;
}
x *= (2.0 - prod); // Heron approximation
}
The precision test is inside an otherwise unconditional loop, so `break` supplies its exit. section 3.2
A wait on a condition variable is different from a successful condition test: the wait can return even though the expression governing the work has not changed. Put the wait inside a loop that rechecks that expression, including any finished-state test. TAKEAWAY: waking up is not, by itself, a stopping criterion. section 20.5










