for, while and do-while
The logger now repeats itself all day long: add up 24 hourly readings, wait until the sensor is ready, show a settings menu at least once. C has three loops, and each one matches one of these jobs. Pick the matching loop and most off-by-one bugs never get written.
The rule
for counts, while waits, do-while acts once before asking.
for puts the start, the test and the step on one line. It is the natural fit when you know how many times to repeat:
int hourly[24] = {0}; /* filled in by the sensor code */
long total = 0;
for (int h = 0; h < 24; h++) {
total += hourly[h];
}The order is: run int h = 0 once; test h < 24; if true, run the body, then h++, and test again. A variable declared in the first part (C99 and later) exists only inside the loop.
while tests first and repeats as long as the condition holds. If the condition is false at the start, the body never runs:
while (!sensor_ready()) {
/* keep waiting */
}do … while runs the body first and tests afterwards, so the body always runs at least once. Note the semicolon at the end:
int choice;
do {
choice = show_menu();
} while (choice != 0);for (;;) with every part empty is the conventional "loop forever"; embedded programs often wrap their whole main job in one. The greenhouse board does exactly that: read the sensor, log the value, wait a minute, repeat until the power goes off.
The shortcut
Count the iterations before you trust a for loop. For for (i = a; i < b; i += s) with a < b, the values are a, a + s, a + 2s … up to the last one below b. List the first and last values, then count.
The loop
for (int i = 1; i <= 10; i += 3)
Reading past the end of an array is undefined behaviour. C will not stop you, so the counting habit is your protection. For arrays, the pattern i = 0; i < length is nearly always right.
Drills
Answer fast — trust the rule.
How many times does for (int i = 0; i < 5; i++) run its body?
How many times does for (int i = 1; i <= 10; i += 3) run its body?
After int n = 10; do { n++; } while (n < 5);, what is n?
After int n = 10; while (n < 5) { n++; }, what is n?
With int hourly[24], what does for (int h = 0; h <= 24; h++) total += hourly[h]; do on its last pass?
Remember
- for counts, while waits, do-while acts once before asking.
- Shortcut: list the first and last values of the counter and count the passes; for arrays use
i = 0; i < length. - Trap:
<=where you meant<reads past the end of the array, which is undefined behaviour.
