Computation
3.4 Statements
3.4.2 Iteration
if (val<0) val=0;
[[fallthrough]];
case unchecked:
// ... use val ...
break;
}
The [[fallthrough]] is an attribute making our intent explicit.
Try This
Rewrite your currency converter program from the previous TRY THIS to use a switch-statement. Add a conversion from Swiss francs. Which version of the program is easier to write, understand, and modify? Why?
Click here to view code image
int main()
// calculate and print a table of squares 0-99 {
int i = 0; // start from 0 while (i<100) {
cout << i << '\t' << square(i) << '\n';
++i; // increment i (that is, i becomes i+1) }
}
The notation square(i) simply means the square of i. Later, we will explain how to get it to mean that (§3.5).
No, this first modern program wasn’t actually written in C++, but the logic was as is shown:
We start with 0.
We see if we have reached 100, and if so we are finished.
Otherwise, we print the number and its square, separated by a tab ('\t'), increase the number, and try again.
Clearly, to do this we need
A way to repeat some statement (to loop)
A variable to keep track of how many times we have been through the loop (a loop variable or a control variable), here the int called i
An initializer for the loop variable, here 0
A termination criterion, here that we want to go through the loop 100 times
Something to do each time around the loop (the body of the loop)
The language construct we used is called a while-statement. Just following its distinguishing keyword, while, it has a condition “on top” followed by its body:
Click here to view code image
while (i<100) // the loop condition testing the loop variable i
{
cout << i << '\t' << square(i) << '\n';
++i; // increment the loop variable i }
The loop body is a block (delimited by curly braces) that writes out a row of the table and increments the loop variable, i. We start each pass through the loop by testing if i<100. If so, we are not yet finished, and we can execute the loop body. If we have reached the end, that is, if i is 100, we leave the while- statement and execute what comes next. In this program the end of the program is next, so we leave the program.
The loop variable for a while-statement must be defined and initialized outside (before) the while-statement. If we fail to define it, the compiler will give us an error. If we define it, but fail to initialize it, most compilers will warn us, saying something like “local variable i not set,” but would be willing to let us execute the program if we insisted. Don’t insist! Compilers are
almost certainly right when they warn about uninitialized variables.
Uninitialized variables are a common source of errors. In this case, we wrote
int i = 0; // start from 0
so all is well.
Basically, writing a loop is simple. Getting it right for real-world problems can be tricky, though. In particular, it can be hard to express the condition correctly and to initialize all variables so that the loop starts correctly.
Try This
The character 'b' is char(’a’+1), 'c' is char(’a’+2), etc. Use a loop to write out a table of characters with their corresponding integer values:
a 97 b 98 ...
z 122
3.4.2.2 Blocks
Note how we grouped the two statements that the while had to execute:
Click here to view code image
while (i<100) {
cout << i << '\t' << square(i) << '\n';
++i; // increment i (that is, i becomes i+1) }
CC
A sequence of statements delimited by curly braces { and } is called a block statement or a compound statement. A block is a kind of statement. The empty block { } is sometimes useful for expressing that nothing is to be done.
For example:
Click here to view code image
if (a<=b) {
// do nothing }
else { // swap a and b:
int t = a;
a = b;
b = t;
}
3.4.2.3 for-statements
Iterating over a sequence of numbers is so common that C++, like most other programming languages, has a special syntax for it. A for-statement is like a
while-statement except that the management of the control variable is
concentrated at the top where it is easy to see and understand. We could have written the “first program” like this:
Click here to view code image
int main()
// calculate and print a table of squares 0-99 {
for (int i = 0; i<100; ++i)
cout << i << '\t' << square(i) << '\n';
}
This means “Execute the body with i starting at 0 incrementing i after each execution of the body until we reach 100.” A for-statement is always
equivalent to some while-statement. In this case Click here to view code image
for (int i = 0; i<100; ++i)
cout << i << '\t' << square(i) << '\n';
means
Click here to view code image
{
int i = 0; // the for-statement initializer while (i<100) { // the for-statement condition cout << i << '\t' << square(i) << '\n'; // the for-statement body ++i; // the for-statement increment }
}
AA
Some novices prefer while-statements and some novices prefer for-statements.
However, using a for-statement yields more easily understood and more maintainable code whenever a loop can be defined as a for-statement with a simple initializer, condition, and increment operation. Use a while-statement only when that’s not the case.
XX
Never modify the loop variable inside the body of a for−statement. That would violate every reader’s reasonable assumption about what a loop is doing. Consider:
Click here to view code image
// bad code:
for (int i = 0; i<100; ++i) { // for i in the [0:100) range cout << i << '\t' << square(i) << '\n';
++i; // what’s going on here? It smells like an error!
}
Anyone looking at this loop would reasonably assume that the body would be executed 100 times. However, it isn’t. The ++i in the body ensures that i is incremented twice each time around the loop so that we get an output only
for the 50 even values of i. If we saw such code, we would assume it to be an error, probably caused by a sloppy conversion from a while-statement. If you want to increment by 2, say so:
Click here to view code image
// calculate and print a table of squares of even numbers in the [0:100) range:
for (int i = 0; i<100; i+=2)
cout << i << '\t' << square(i) << '\n';
AA
Please note that the cleaner, more explicit version is shorter than the messy one. That’s typical.
Try This
Rewrite the character value example from the previous TRY THIS to use a
for-statement. Then modify your program to also write out a table of the integer values for uppercase letters and digits.
There is also a simpler “range-for-loop” for traversing collections of data, such as vectors; see §3.6.