A "Feild" Guide to Programming with C++
Introductory programming notes by Henry FeildChapter 5: Loops
Important takeaways
- loops are programming constructs that allow us to repeatedly execute a block of code until some condition is met
- there are three kinds of loops we'll use in class, each with its
strengths:
- while—checks a condition and if true executes a block of code; this repeats as long as the condition is true
- do-while—executes a block of code and then checks a condition; repeats as long as the condition is true
- for—useful for iterating over an interval with a starting, ending, and updating value
Contents
Introduction
Up until know, if we've wanted to do something more than once in our program, like prompt the user for the same information, we just repeated the code to do so. If you want to prompt the user a couple of times, this doesn't seem so bad. What if you want to prompt the user fifty times? 100 times? Forever until some condition is met? It's not practical, or in the latter case, possible, to copy and paste our code that many times. Programming languages have something built in to address this: loops. Loops are constructs that allow us to repeat a block of code until some condition is met. For example, we might prompt a user until they enter valid data, or interact with a user until they indicate they want to exit the program.
There are three C++ loop structures we will consider in this class: while loops, do-while loops, and for loops. Each has its own specialties, but when it comes right down to it, we can actually convert any loop into any other loop with a little extra (or less) code. So, their differences are just conveniences. We describe each below in turn.
(Back to top)While loops
while loops are the most conceptually easy to understand. They work as follows:
while(condition) { // Block of code to execute only if the condition evaluates to true. // At the end, go back to the top and check the condition again. }
The condition is the same kind of condition you use in an if statement. The block code in between the curly braces is the body of the loop and is just like the code inside of an if statement—it only executes when the condition is true. Unlike an if statement, though, once we hit the bottom of the block, we loop back up to the top of the while and re-check the condition. If the condition evaluates to true, then we execute the block, otherwise we skip it. This brings up an important point: at some point, the condition should evaluate to false, otherwise, the loop will keep going forever (called an infinite loop); this is bad and will likely cause your computer to slow down to a crawl and you'll have to force quit your program.
Let's consider an example. Suppose I want to prompt the user for their age. As long as they give me a nonsensical age (e.g., 0 or 140), I want to re-prompt them. Only when they enter one that makes sense do I want to stop. Here's what that would look like:
Here, our condition is age < MIN_AGE || age > MAX_AGE
. This
will evaluate to true or false based on what the user enters at the first
prompt. If the user provides an age that is between MIN_AGE
and
MAX_AGE
, then the condition will evaluate to false, and the while
body will be skipped. If the user enters an age outside of that range, then the
condition will evaluate to true and the body will be executed. There we
re-prompt the user, then we check the condition again, and either execute the
loop body or skip it, etc., etc.
If we never read a new value into the age
variable in the loop
body, then we would wind up with an infinite loop since the only variable in the
condition is age
. We want to avoid that! So, any time you make a
condition for a loop, make sure that there is some way for the condition to
evaluate to true based on what happens in the loop body.
Do-while loops
A somewhat similar looking loop construct is the do-while loop. This is like an upside-down while loop. It starts with the body of the loop, then a condition is checked; if that condition evaluates to true, then the program goes back to the top of the loop body and continues to execute from there. If the condition evaluates to false, the program breaks from the loop and continues on to the code after the loop. An important thing to remember is that a do-while loop executes the body once before the condition is checked. So, no matter what the condition evaluates to, the loop will always execute at least one time.
Here's the general layout:
do { // Block of code to execute -- always executes at least once. } while(condition);
This set up may seem a little strange, so let's talk about why a programmer may
want to use at do-while loop. If we want to prompt and then keep
prompting the user with the same set of instructions until the user enters a
particular value, like "quit"
, then a do-while loop is an
appropriate choice. Let's look at an example where we repeatedly prompt the user
to either increment a sum or quit. The loop only stops when the user selects
the option to quit:
This code starts with a variable to keep track of the sum, sum = 0
.
Within the body of a do-while loop, we prompt the user to either
increment the sum or to quit. If the user selects i
, then we
increment the sum and print out its new value. In the condition of the
do-while, we check if the user selected to quit. If so, we exit the
loop and continue with the program. If the user did not select q
,
then we go back to the top of the loop and execute the loop body, thus
re-prompting the user, etc.
The important things to notice are that 1. the first prompt is always displayed
(that is, the body of the loop is always executed at least once), and 2. we do
not know what the user's response is until we execute the body the first time.
So, we cannot convert this loop to a while loop just by moving the
while(response != 'q')
to the top of the loop, replacing
do
. Rather, we would need to ensure that the condition would always
evaluate to true the first time, which means we would need to initialize
response
to something other than q
.
When should a while loop be used over a do-while loop? This is a great question and one that is a little tricky to answer. In general, a while loop is more appropriate...
- if you want the first prompt text to be different from the re-prompt text, as in our example in the previous section
- if the program has all the information it needs in order to check the condition before the first time the loop body executes
How about a do-while loop? They are generally more appropriate...
- if the evaluation of the condition depends on the body of the loop executing at least once
- if you want to have a single prompt for both the initial prompt and any re-prompts (as in our example in this section)
You can always convert a while loop into a do-while loop and vice versa, but be aware that you will need to modify some code outside of the loop to do so.
(Back to top)For loops
It is very common in programs to want to iterate over a range of values, e.g., perform a loop exactly 10 times, or iterate over every other value from 1 to 100 (e.g., 1, 3, 5, etc.). In the next chapter, we'll need to iterate over data in a list (the first item, second item, etc.). To iterate over a range, we need to know three things:
- where to start (e.g., start at 1)
- when to keep going (e.g., go until we reach 100)
- how to update (increment by 1 or 2 or 10, whatever)
We can do this with a while loop: we set the starting value prior to the loop, we check if we should keep going in our condition, and we update our value at the bottom of the loop. Here's how we can use a while loop to iterate over every value in the range 1–10, printing each value along the way:
Given how often programmers need to iterate (this has to do with arrays, mostly, which we will learn about in the next chapter), there is a special loop construct just for it, and it saves us a whole 1.5 lines of code. It's called a for loop. A loop has the following structure:
for(initializer; loop condition; update) { // Block of code to execute. }
Here's how we would implement our earlier example with a for loop:
In the parentheses after the for
keyword, we have three parts,
separated by semi-colons. The first sets our loop variable to its starting point
(we can declare this prior to the for loop, or at this spot). The
middle one is our loop condition, just like with a while or
do-while loop. The final part is the code to update our loop variable.
The update should make the value of the loop variable approach the condition
that will cause us to break out of the loop, otherwise, we'll just loop forever.
So let's look at a couple of other examples. Suppose we want to loop from 2 to 100, skipping all of the odd numbers. We'll start at 2, end at 100, and update our variable by 2, rather than 1, thus skipping the odds:
Similar to if statements, if a while/do-while/for loop body contains a single line, we don't need the curly braces. So, we can re-write the above code like this:
We'll see more about how for loops can be used with arrays later.
(Back to top)