Additional Material 2 Basic C++ statements and control flow Other kinds of statements control the order in which statements are evaluated. For example, the if statement. if (boolean_expression) statement or if (boolean_expression) statement else statement Examples: if (x > 0) y = x; else z = x; An important kind of statement is the block, to group statements together: { statement1 statement2 ... } For example if (x > 0) { z = x; w = y; } else { z = y; w = x; } Identifiers declared in a block exist only from that point to the end of the block, so int s(3), t(1); if (s == 3) { int w(t); int t(7); s = w+t; } The values of s and t after this peculiar sequence of statements are 8 and 1, respectively. The identifier t defined in the block disappears at the end of the block, so the original t is back in effect at the end of the program. To make programs easier to understand, you should declare identifiers in the smallest scope possible, near where they are used. Another kind of statement is the kind that allows iteration, or repeated execution of the same statement. while (boolexpr) S For example while (x > 0.) { if (x > 1.) ++i; // x /= 2.; x -= 1.; } Presumably, something that happens in the statement following the while will eventually make the boolean expression true. By the way, the use of ++i above is an alias for i += 1. By the same token --i means i -= 1 i++ means t = i, i += 1, t i-- means t = i, i -= 1, t where, in the latter cases, the value of the expression is the value of i before it is changed, not the value after. As a rule, don't use i++ or i-- unless you have a reason to prefer them to one of the alternatives. There are other statements to allow selection (like if) or iteration (like while), though if and while are sufficient. One variation on the while statement is the do while statement. do S while (boolexpr); For example, do { x /= 2; } while (x > 1.); The difference between this and while (x > 1.) { x /= 2; } is that in the first, x is halved once no matter its initial value, where in the second, x is not halved at all unless it initially exceeds 1. Another variation is for (decl-or-arith-stmt boolexpr; arith-expr) S For example, for (i = 0; i < n; ++i) { s += i; } This is exactly the same as i = 0; while (i < n) { s += i; ++i; } but the for statement has places for the initialization, test and increment that are typical of many iterations. Use it when there is clearly a single variable that controls the iteration, and when the number of iterations is known when the first iteration begins. Otherwise, use a while statement. Another variation on the for loop is for (unsigned i = 0; i < n; ++i) { s += i; } Here, the controlling variable i is declared in the for statement, and its scope (the part of the program where it is accessible) does not extend past the statement (in this case, a block statement) that is subject to the for statement. There are two statements that can disrupt the control flow of an iteration. "break" causes control to resume after the loop. while (x > 1.) { double y(x/2.); if (y < x) break; x = y; } In this silly example, y is always less than x, so the assignment (x=y) will never be evaluated, and the booelan expression (x>1.) will be evaluated only once. The continue statement returns control immediately to the boolean expression controlling the loop, and the iteration will continue depending on the value of the boolean expression. while (x > 1.) { x -= 2.; if (3*y > x) continue; y = x/3.; } This silly example could be written without the continue, as while (x > 1.) { x -= 2.; if (3*y <= x) y = x/3.; } In fact, while the break is awkward but occasionally useful, the continue is rarely needed. Two more control statements deserve scant mention. First the switch statement: switch (integral-value) { case const-val1: . . . case const-val2: . . . default: . . . } Switch provides a multi-way branch. Unlike a series of if ... else if ... else if ... else... statements, the switch statement provides many difference choices of where to go from a single point. The flow of control resumes at the case label that matches the integral-value, or at the default label (if there is one) otherwise. An example: char c; switch (c) { case 'A': cout << "You are an excellent student!\n"; break; case 'B': cout << "You have promise, but must work harder.\n"; break; case 'C': cout << "Have you considered a change in majors?\n"; break; case 'D': cout << "If you do not do better next time,\n"; /* FALLTHROUGH */ case 'F': cout << "You should leave the university\n"; } Note that both cases 'D' and 'F' print the line about leaving the university. Once control is transferred to a label, consecutive statements are executed until either a break is encountered, or the switch block ends. Having a break after every case is normal, and leaving the break out is a fairly common mistake, so if you leave it out on purpose, be sure to make that decision explicit with a comment. It's also a good idea to package all the statements for a particular case into a single block statement.