Chapter 3 Part I Lecture Notes

Thus far we have been exposed to a few source programs which explore simple
aspects of C++.  This chapter is the core of the course since it introduces
some of the most important control structures.

Let's begin with the order of execution of a program.  Chapter 1 presented
examples that seemed to execute from line to line.  This is true in general.
Execution is a sequential process: start at the first line in main() and
continue until the last line of main() executing line by line.

Chapter 2 also presented you with the assignment operator (=).  This allows us
to assign data from some variable to another destination variable.

Also presented in the previous chapter were the comparison operators. However,
there were no examples given of how to utilize them.  In this chapter we will
consider control structures which interrupt the sequential flow of a program
by using the comparison operators.



IF-THEN

The first control structure we will consider is the if-then statement.
This is very simple.  It has the following syntax (note semicolons):

  if (condition) statement;

If the condition inside the parentheses is true then execute the statement
that immediately follows.

For example,

  A = 10
  if (A > 11) A = 5;

If this case the condition fails so A is still 10 after the IF statement. Here
is an example program illustraing the IF-THEN statement.

#include <iostream.h>

int main()
{
  int num;

  cout << "Enter an integer>> " << endl;
  cin >> num;
  if (num == 10) cout << "The integer you entered is ten." << endl;

  return 0;
}



IF-THEN-ELSE

The second control structure is related to the IF-THEN statement.  An
IF-THEN-ELSE has three parts specified by the following syntax (again, note
semicolons):

  if (condition) statement1;
    else statement2;

If the condition is true, execute statement1 exactly like the IF-THEN, however,
if the condition fails, execute the ELSE part: statement2.

For example,

  A = 10
  if (A > 11) A = 5;
    else A = 2;

If this case the condition fails so A is assigned the value 2..
Here is a simple example program which illustrates this control structure.

#include <iostream.h>

int main()
{
  int num;

  cout << "Enter an integer>> " << endl;
  cin >> num;
  if (num > 10) cout << "The integer you entered is greater than ten." << endl;
    else cout << "The integer you entered is less than or equal to ten.";

  return 0;
}



MULTIPLE CONDITIONS

Inside a condition, you are allowed to have as many comparisons as desired.
Consider an example.
//Multiple comparisons possible
#include <iostream.h>

int main()
{
  int num;

  cout << "Enter an integer>> " << endl;
  cin >> num;
  if ((num >= 0) && (num < 10))
    cout << "The integer you entered is between zero and ten." << endl;

  return 0;
}

In this case there are two comparisons separated by && (logical and).  If
multiple comparisons are necessary, they must be separated by a logical
operator: either the logical and operator (&&) or the logical or operator (||).
These operate as in boolean logic: A && B is true only when both A and B are
true.  A || B is true when either A or B is true.  The above example
therefore tests to see if an integer x is between 0 and 10, not inclusive of
10: (0 <= x < 10).



NESTED IFs

The syntax of the IF statement requires some statement immediately follow the
condition and the ELSE.  This does not have to be assignment statement as in
the previous examples.  This requirement may be satisfied by another if
statement.  This option could present us with a situation where we have many
IF-ELSE statements within more IF-ELSE statements.  This is called nesting.
And in situation we are nesting IF statements.  Consider a small code example.

  int num;

  cout << "Enter an integer>> " << endl;
  cin >> num;
  if (num == 1) cout << "You entered the number one," << endl;
  else if (num == 2) cout << "You entered the number two," << endl;
       else if (num == 3) cout << "You entered the number three," << endl;
            else cout << "You didn't enter a 1, 2, or 3." << endl;


Note that the indentation of the IFs match the corresponding ELSEs.  This
clarifies which ELSE is applied to which IF.  This example outputs a sentence
to the user, indicating whether an integer entered by the user is a 1, 2, 3,
or neither.

Clearly, nesting can become confusing even with a few IF statements.  That is
why there is another control structure which can make this situation more
comprehensible.



SWITCH

The switch statement can be thought of as a replacement control structure for
nested IFs.  The switch statement is used in a situation where you may have
many cases each of which requires a different set of corresponding statements
that will be executed.

Syntax is as follows:

  switch (control variable or expression) {

    case label1:  statement11;
                  statement12;
                      ...
                  statement1N;
                  break;

    case label2:  statement21; 
                  statement22; 
                      ... 
                  statement2X; 
                  break; 

    case label3:
    case label4:  statement31; 
                  statement32; 
                      ... 
                  statement3Y; 
                  break; 

    ...
   
    case labelm:  statementm1;  
                  statementm2;  
                      ...  
                  statementZ;  
                  break;  

    default:      statements;
  };

Note that the cases are separated from their corresponding statement lists
by a colon.

You are also allowed to have more than one case execute the same statement
list: label3 and label4.

There is also a default statement which is used when the control variable does
not match any of the cases.  A well-constructed switch statement will always
have a default statement that will issue error messages or some means to
indicate that no cases were matched.

There is also another key word which appears in the switch statement: break.
The break statement causes an immediate exit from the switch statement. Without
the break statements after each case, all statements below it (the statements
belonging to another label) would be executed. 

Consider the nested-if example seen previously as written with a switch
statement.

  int num; 
 
  cout << "Enter an integer>> " << endl; 
  cin >> num; 
 
  switch(num) 
  { 
    case 1: cout << "You entered the number one." << endl; break;
    case 2: cout << "You entered the number two." << endl; break;
    case 3: cout << "You entered the number three." << endl; break;
    default: cout << "You didn't enter a 1, 2, or 3." << endl; 
  }; 

The default case here prints an error which indicates the user did not enter
one of the three expected cases.


META SWITCH NOTES:

The control variable can either be character or integer data types.

If you have an integer data type, you may include more than the control
variable: you may have an expression which must evaluate to an integer value.
The following are legal switch control variable statements:

  int n;
  int m;

  switch(n % m)
  switch(n - m)
  switch(n + m)

Other control expressions are also possible, these are only a few examples.
You may divide ( n / m ) as well but this comes with a caveat.  When dividing
an integer by an integer, we are not guaranteed that the result is an integer,
therefore your results may be unexpected.

Chris Alvin