Control Structures
 

Flow of Control:

Flow of control through a program segment is implemented with three basic types of control structures:

Useful tools for building programs or program segments

Logical Operators:

The arithmetic comparison operators in C++ work much like the symbols we use in mathematics.  Each of these operators returns a 0 for false and a 1 for true.
  x == y        // x is equal to y
  x != y        // x is not equal to y
  x < y         // x is less than y
  x <= y        // x is less than or equal to y
  x > y         // x is greater than y
  x >= y        // x is greater than or equal to y

We also have Boolean operators for combining expressions.  Again, these operators return 0 for false and 1 for true

  x && y        // the AND operator -- true if both x and y are true
  x || y        // the OR operator -- true if either x or y (or both) are true
  !x            // the NOT operator (negation) -- true if x is false

These operators will be commonly used as test expressions in selection statements or repetition statements (loops).
 

Short Circuit Evaluation:

The && and || operators also have a feature known as short-circuit evaluation.

In the Boolean AND expression (x && y), if x is false, there is no need to evaluate y (so the evaluation stops).

Similarly, for the Boolean OR operation (x || y), if the first part is true, the whole thing is true, so there is no need to continue the evaluation. The computer only evaluates as much of the expression as it needs. This can allow the programmer to write faster executing code.
 

The bool type:

C++ also provides one extra atomic data type, called bool
The keywords true and false are used to represent values of type bool.  (They are implemented similar to the C method, using integer values 1 and 0 for true and false, respectively).

Example:

  bool answer;
  answer = true;

Selection Statements:

The if statment: Most common selection statement is the if statement. Basic syntax:
   if (expression)
      statement
   else
      statement

The else clause is optional.

Note: In this format, the expression part can be any expression, but it must be enclosed in parintheses ( ).  Any expression that evaluates to 0 is interpreted as false.  Anything else is interpreted as true.  The statement part can be a single line statement, or it can be a compound statement.  If it is a compound statement, remember that it must be enclosed in set braces { }.

Examples:


   if (grade >= 68)
      cout << "Passing";

// Notice that there is no else clause.  If the grade is below 68, we move on.


   if (x == 0)
      cout << "Nothing here";
   else
      cout << "There is a value";

// This example contains an else clause.  The bodies are single statements.


   if (y != 4)
   {
      cout << "Wrong number";
      y = y * 2;
      counter++;
   }
   else
   {
      cout << "That's it!";
      success = 1;
   }

Multiple statements are to be executed as a result of the condition being true or false.  In this case, notice the compound statement to delineate the bodies of the if and else clauses.



Be careful with ifs and elses.  Here's an example of an easy mistake to make.  If you don't use { }, you may think that you've included more under an if condition than you really have.

// What output will it produce if val = 2?   Does the "too bad" statement really go with the "else" here?

   if (val < 5)
      cout << "True\n";
   else
      cout << "False\n";
      cout << "Too bad!\n";

* Indentation is only for people!  It improves readability, but means nothing to the compiler.

Miscellaneous if/else examples


The switch statement:  Another type of selection statement is the switch statement, which is good for occasions in which you are selecting among many different choices of values.  The syntax format is:

switch (expression)
{ 
    case constant: 
        statements 
    case constant: 
        statements 

    ...  (as many case labels as needed) 

    default:            // optional label 
        statements 
} 

The switch statement evaluates the expression, and then compares it to the values in the case labels.  If it finds a match, execution of code jumps to that case label.  The values in case labels must be constants, which means that you may use an integer literal, a character literal, or a constant variable.  You may not have case labels with regular variables, strings, or floating point literals.  The compiler must know the exact value of each label, without ambiguity.  If you want to execute code only in the case that you jump to, remember to end the case with a break statement!

Switch Example 1 -- syntactically correct, but logically incorrect

Switch Example 2 -- corrected version of Example 1

Example 3:  This examples uses character literals for the case labels. It also allows for both upper and lower case menu choices.

cout << "Enter menu choice: "; 
cin >> option; 
switch(option) 
{ 
    case 'A': 
    case 'a': 
        result = a + b; 
        break; 
    case 'S': 
    case 's': 
        result = a - b; 
        break; 
    case 'M': 
    case 'm': 
        result = a * b; 
        break; 
    default: 
        result = 0; 
} 

Repetition Statements:

Repetition statements are handled with some type of loop.  The three basic types are while, do/while, and for loops.
In all of these syntax formats, the expression can be any type of expression, and the statement can be a single statement (ending with a semicolon ;) or a compound statement (enclosed in set braces { } ).

Formats:

 while (expression) 
    statement 
  

 do 
    statement 
 while (expression); 
  

 for (initial condition; test expression; iterative statement) 
    statement 


Examples:  Each of the following loops adds up all of the numbers between 1 and 50.  However, here are three separate ways of doing it.

 // while loop example 
 // loop body runs 50 times, condition checked 51 times 
 int i = 1, sum = 0; 
 while (i <= 50) 
 { 
    sum += i; 
    i++; 
 } 
 cout << "Sum of numbers from 1 through 50 is " << sum; 
  

 // do/while loop example 
 // loop body runs 50 times, condition checked 50 times 
 int i = 1, sum = 0; 
 do 
 { 
    sum += i; 
    i++; 
 } while (i <= 50); 
 cout << "Sum of numbers from 1 through 50 is " << sum; 
  

 // for loop example 
 // loop body runs 50 times, condition checked 51 times 
 int sum = 0; 
 for (int i = 1; i <= 50; i++) 
 { 
    sum += i; 
 } 
 cout << "Sum of numbers from 1 through 50 is " << sum; 

Special notes about for loops:

1)  It should be noted that if the control variable is declared inside the for header, it only has scope through the for loop's execution.  Once the loop is finished, the variable is out of scope:
  for (int counter = 0; counter < 10; counter++) 
  {    (loop body)    } 

  // The variable "counter" is now out of scope 

This can be avoided by declaring the control variable before the loop itself.

  int counter;    // declaration of control variable 

  for (counter = 0; counter < 10; counter++) 
  {    (loop body)    } 

  // The variable "counter" is still in scope 

2)  For loops also do not have to count one-by-one, or even upward.  Examples:

  for (i = 100; i > 0; i--)
  for (c = 3; c <= 30; c+=4)

The first example gives a loop header that starts counting at 100 and decrements its control variable, counting down to 1 (and quitting when i reaches 0).  The second example shows a loop that begins counting at 3 and counts by 4's (the second value of c will be 7, etc).
 

Special statements:  break and continue

There are two special statements that alter the flow of control in some of the above structures:  break and continue.

break:  causes immediate exit from switch structures and all three types of loops.
continue:  only used in loops.  A continue statement in a loop causes that loop execution to end, and the next loop iteration begins (i.e. continue causes the remainder of the loop body to be skipped for that loop iteration).

More examples of selection and repetition code