Folder101   Home Notes Quiz Assigns Info  
Forum Forum
101 Home 101
 
  C++ Level 2

Ptogram Flow & Conditional Statements

Intro - Program Flow Control

Relation & Equality Operators

Logical Operators

Selection Statements>>: If-Else

Nested Ifs

Switch

Extension Work


  Intro- Program Flow Control

You would be very limited in your programming if you were restricted to sequential line-by-line code execution, without any control over the flow of your code execution.

For finer control over the sequence in which lines are executed in our code you need to use selection and iteration statements. These statements allow you to control the flow of program execution.

Selection statements are:-

  • If - Else
  • ? operator
  • Switch

Iteration statements are:-

  • For
  • While
  • Do-While

However before looking at these control statements you need to understand equality , relational and Boolean operators. 


  Relational & Equality Operators

Relational and equality operators allow us to compare the relationship between two quantities.  The result of evaluation will be a true or a false.  For example, 3 < 5 is like asking " 3 is less than five - true or false?", which results in an answer of true since 3 is certainly less than 5.

In C and C++, true is any value other than zero.  False is zero.  Expressions that use relational operators return a value of zero for false and 1 for true.

The table below shows some operators.  The first two are equality operators, the rest are relational operators.

Operator

Name

 Example/Description

==      

equal to  

x == y   // if x is equal to y the expression evaluates to 1, otherwise returns 0

!=  

not equal to  

x != y    // if x is not equal to y the expression evaluates to 1 otherwise, returns 0

<  

less than    

x < y  // if x is smaller than y the expression evaluates to 1, otherwise returns 0

<=     

less than or equal to

x <= y  // if x is smaller or equal to y the expression evaluates to 1, otherwise returns 0

>   

greater than

x > y  // if x is greater than y the expression evaluates to 1, otherwise returns 0

>=

greater than or equal to  

x >= y  // if x is greater than y the expression evaluates to 1, otherwise returns 0

Here are a few examples;-

10 < -5;  returns 0 which means false

11.5 >= 2;  returns 1 which means true

int i = 10, j = 3;

i == j  returns 0 which means false

i != j  returns 1 which means true

i <= (j + 7)  returns 1 which means true

~Now try the activity~

Activity 8A

State if the following expressions return a 1 or 0.

    int i = 2, j = 1;

    1. 20 < -5
    2. 20 <= (-5 + 25)
    3. i > j++
    4. i > ++j

Why not check your answers by creating your own code.


  Logical Operators

C++ contains the Logical operators AND (&&), OR ( || ) and NOT ( ! ).  These operators are used with expressions that evaluate to a 1 or 0, which are the equivalent of true or false in C++.  Let's look at some examples:-

Example of && (AND)

You can imagine the AND operator && to mean..

(this expression) AND (this expression) must both evaluate to true

Here is a truth table for AND :-

x

y

Q = (x && y)

0 0 0
0 1 0
1 0 0
1 1 1

As an example:-

(4 < 2) // evaluates to 0 which means false

(1 < 2) // evaluates to 1 which means true

.. and the following expression means -  if both sides of the && evaluate to true then return a true, else return a false.

(4 < 2) && (1 < 2) 

So let's rewrite the expression as:-

0 && 1   

So the whole expression evaluates to 0 which means false

Example of || (OR)

You can imagine the OR operator ||   to mean..

(this expression) OR (this expression) must evaluate to true

Here is a truth table for OR :-

x

y

Q = (x || y)

0 0 0
0 1 1
1 0 1
1 1 1

As an example:-

(4 < 2) // evaluates to 0 which means false

(1 < 2) // evaluates to 1 which means true

...and the following expression means -  if one or both sides of the || evaluate to true then return a true.  If both sides evaluate to false then return a false.

(4 < 2) || (1 < 2) 

So let's rewrite the expression as:-

0 || 1   

So the whole expression evaluates to 1 which means true

Example of ! (NOT)

You can imagine the NOT operator !   to reverse the Boolean result it is operating on:-

!(1)  // evaluates to 0

!(0)  // evaluates to 1 which means true

Here is a truth table for OR :-

x

Q = (!x)

0 1
1 0

As an example:-

(4 < 2) // evaluates to 0 which means false

(1 < 2) // evaluates to 1 which means true

...and the following expressions mean -  return a false if expression is true and vice-versa.

!(4 < 2) // evaluates to !0 which is reversed to a 1

!(1 < 2) // evaluates to !1 which is reversed to 0

The table below shows the Logical operators and also some bitwise operators.

Operator

Name

 Example/Description

&&   

Logical AND   

Produces a true if both operands are true

||

Logical OR   

Produces a true if one or both of the operands is true

!

Logical NOT

Reverses a false to a true and vice-versa

&

Bitwise AND

Produces a true if both operands are true

|

Bitwise OR

Produces a true if one or both of the operands is true

^

Bitwise XOR

Produces a true only if one of the operands is true

The reason for listing the bitwise operators is to highlight a common mistake made by beginners which is to confuse the logical operators, && and || with the bitwise operators & and |.
For example, there is a major difference between the way the bitwise & and logical && operator works.  Consider the following:-

1 && 2 // evaluates to 1

or

1 & 2 // evaluates to 0

In the first case, where the double ampersand is used, the expression is evaluated in the following way:-

  • Since any number except 0 in C++ is regarded as true, the equivalent of 1 && 2 is...

    true && true

    which evaluates to true.

In the second case, where the single ampersand is used, the expression is evaluated in the following way:-

  • The number 1 in binary is 01. The number 2 in binary is 10. The bitwise operator & means to logically compare two operands bit-by-bit. So, comparing 01 with 10 bit-by-bit we end up with the result of 0.
    I.e.    01
             10 &
          = 00

The bitwise operator | is also different from the logical operator |. It also compares two operands bit-by-bit, comparing each pair of bits and returning a 1 or 0 for each pair.

I.e.    01
         10 |
      = 11

Just one final remark about the logical operators && and ||. They always check the first operand to see if it is a true or a false.  In the case of the &&, only if the first operand evaluates to true will it check the second operand. In the case of the ||, only if the first operand evaluates to false will it check the second operand.

~Now try the activity~

Activity 8B

Given the following declaration, evaluate the Boolean expressions and state if the result is a 1 or a 0.

int a = 2, b = 6;

  1. (a < b) && (a <=2)

  2. (a != b) || (b == 6)

  3. !(a > b) && ( ( b > = 6) || ( b == a) )

  4. Copy and compile the following code:-

    void main () {
       unsigned short flags1;
       unsigned short flags2;

       flags1 = 010;
       flags2 = 001;

       cout << "Bitwise Operator: " << (flags1 & flags2) << endl;
       cout << "Logical Operator: " <<(flags1 && flags2) << endl;

    }

    Before running your code, can you work out what the output will be?

  5. Examine the code below.  What do you think the output will be?   If you run the code you will see how dangerous it is to confuse the bitwise operator & and the logical operator &&.  Make one correction to the code so that the program will run without crashing.
  6. void main(){

       int a = 0;

       if (  (a != 0)  &  (10/a > 1)  ) {
          cout << "evaluated to true\n";
       }

       else {
          cout << "evaluated to false\n";
       }
    }

  7. If you change the code above so you use the logical operator &&, does the second operand 10/a > 1 get evaluated? What if you change the value of a to something other than 0. Will it get evaluated then?

Why not check your answers using code.


  Selection Statements:>> If-Else

Selection statements allow us to choose between alternative actions within a program.  C++ has two distinct selection statements.  The if statement and the switch statement.  We shall examine the if statement first. 

If Statement

The syntax of the if statement is:-

if (condition) {

    statement;

}

where condition is any expression that evaluates to a true or false .  If condition evaluates to a true then statement is executed otherwise statement will be bypassed.  Here is an example:-

int age = 20;

if (age >= 18) {
    cout << "You are an adult\n";
}

Since the expression age >= 18 evaluates to true, "You are an adult" is displayed.

Taking the if statement further we have the if-else statement.  The syntax is:-

if (condition) {

    statement;

}

else {

    statement;

}

where again, condition is any expression that evaluates to a true or false .  If condition evaluates to a true then the first statement is executed otherwise statement will be bypassed.  However, the statement in the else block will be executed instead.   Here is an example:-

if (age >= 18) {
    cout << "You are an adult\n";
}
else {
    cout << "You are a minor\n";
}

If age is set to value of 10, what will be printed out?

Here is another example:-

int i  = 10, j = 4;

if ( i < j ) {

    cout << "i is smaller than j";

}

Since  i< j evaluates to 0, the statement inside the if block is not executed.  However, given...

if ( !(i < j) ) {

    cout << "i is smaller than j";

}

The statement inside the if block is executed.  This is because  i< j evaluates to 0 but the NOT operator ! reverses this to a 1.  

Here is another example:-

if ( (condition1) && (condition2) ) { do something }  e.g.

if ((3 < 4) && (6 > 2)) {

    do something..

    do some more;

}

This statement means if condition 1 AND condition 2 are true then execute the statements inside the if block.  Since (3 < 4) evaluates to true but (6 > 2) evaluates to false then the result of (3 < 4) && (6 > 2) is false .  The statements do not get executed.

Here is another example:-

if ( (condition1) || (condition2) )  { do something } e.g. 

if ((3 < 4) || (6 > 2)) {

    do something..

    do some more;

}

This statement is very similar to the one above except that the || means OR.  So the statement translates to if condition1 OR condition2 are met then execute the statements inside the if block. Since (3 < 4) evaluates to true but (6 > 2) evaluates to false then the result of (3 < 4) || (6 > 2) is true .  The statements do get executed.   

Yet another example:-

int num = 6;

if (num == (10 - 4)) {

    do something..

    do some more;

}

The condition in this case uses the equality operator ==.  Since (10 - 4) is 6 and num is certainly equal to 6 then the expression num == (10 - 4) evaluates to true.

#Warning#   Don't make the mistake of using  the assignment operator = to test for equality.  E.g. 

if (num = (10 - 4)) {

...would assign the value of 6 to num. Since the number 6 is not zero, this is equivalent to true and the if block would get executed.

One last example:-

char[4]  ch   =  "cat";

if (ch == "dog") {

    do something..

    do some more;

}

Here I am testing if two strings are equal.  In this case I am testing if the string that ch refers to (i.e. "cat") is the same as the string "dog".  Of course "cat" and "dog" are not the same so this evaluates to false and the statements inside the if block do not get executed.

~Now try the activity~

Activity 8C

  1. Write a program using If statements, that reads in a numbers between 1 and 10 and displays the phrase "number is a prime" or "number is not a prime" as appropriate. Prime numbers between 1 and 10 are 1, 2, 3, 5 and 7. 

You can use the lines

int num;

cin >> num;

to get a number input 


  Nested Ifs

Nested Ifs are very common in programming. A nested If of If-Else is contained within another If or If-Else block. Let's have an example:-

if (i) {

   if (j) statement1;

   else statement2; // associated with if(j)

}

else { // associated with if(i)

   statement3;

}

We can see there is an outer If (j) block, associated with the bottom else. Also there is an inner If (j) block associated with the inner else.

Here is another example:-

if (i) {

   if (j) cout << "I like all animals but";

   if (k) cout << "cats are the best";

   else cout << "dogs are the best"; // associated with if (k)

}

Setting i to 1, j to 0 and k to 0 what message do you think you will end up with?

You should end up with>> "dogs are the best"

The ANSI standard allows 15 levels of nesting. However, too many levels is not encouraged because it is hard to read. If you need lots of nested levels it is better to use a switch statement.

Another common programming construct is the if-else-if ladder. In general form it looks like:-

if (condition1)
    statement1;
else if (condition2)
    statement1;
else if (condition3)
    statement3;
...
...
else
    statement;

The conditions are all evaluated from the top downward. As soon as a true condition is found than the statement associated with it is evaluated. If none of the conditions are true then the statement associated with the final else is executed.

You should note that if you wish for more than one statement to be executed in an if block, then you have to use the block indicators{ and }. I.e.

if (condition1) {
    statement1;
    statement2;
}
else if (condition2) {
    statement3;
    statement4;
}

~Now try the activity~

Activity 8D

  1. Write a program that allows a user to guess a number between 1 and 10.  Print out appropriate messages to tell the user that their guess is "Too high " or "Too low " if the guess if wrong or "Correct" if the guess is right.

  Switch

Switch is a multiple-branch selection statement used to successively test the value of an expression against a list of character or string values. When a match is found, the statements associated with the matched case are executed. The general form of the switch statement is:-

switch (expression) {
   case somevalue:
      statement sequence;
      break;
   case somevalue2:
      statement sequence;
      break;
   case somevalue3:
      statement sequence;
      break;
   ...
   ...
   default:
      statement sequence;
}

The value of expression is compared in order, against each of the values (somevalue, somevalue2 etc.) specified in the case statements. The first match wins and any statements associated with the case are executed until a break statement is reached. If a match is not found then the statements associated with the default case are executed.

The default case is optional and if not present then no action takes place if all matches fail.

The break statement is a jump statement. When a break is encountered, program execution jumps to the nearest line of code following the switch block, i.e. after the end switch } bracket.

Here is a simple example to illustrate:-

switch ( Grade ) {
   case 'A':
      cout << "Excellent\n";
      break;
   case
'B':
      cout << "Good\n";
      break;
   case
'C ':
      
cout << "Tolerable\n";
      break;
   
case
'D':
      cout << "Poor\n";
      break;
   default
:
      cout << "You grade is a mystery\n";
}

If Grade was given a value of 'C' then the output would be 'Tolerable'.

Here are a few things to note about the switch statement.

  1. Unlike the multiple decision statement that can be created using if-else, the switch statement evaluates the conditional expression and tests it against numerous values.
     
  2. Unlike if-else, switch can only test for equality, it cannot evaluate a relational or logical expression (i.e. Grade < 'C')
     
  3. The value of the expression in a switch statement must be an ordinal type i.e. integer, char, short,long, etc.  Float and doubles are not allowed.

Now let's consider the importance of the break statement.

Consider what happens if I leave the break statement out of the example code from above:-

switch ( Grade ) {
   case 'A':
      cout << "Excellent\n";
   case
'B':
      cout << "Good\n";
   case
'C ':
      
cout << "Tolerable\n";
   case 'D':
      cout << "Poor\n";
   default:
      cout << "You grade is a mystery\n";
}

The output if Grade were set to 'C' would be

Tolerable
Poor
Your grade is a mystery

This is because, when a match is found, the statements associated with the matched case are executed as normal. However, without a break statement to jump to the end of the switch block, execution continues into the following case's statements until either a break is found or the end of the switch is reached.

Sometimes this can be useful. Consider the following:-

cout << "Please enter A or D\n";
cin >> userInput;
switch
( userInput ) {
   case 'a':
   case 'A':
      cout << "'You chose the A option\n";
      break;
   case 'd':
   case 'D':
     cout << "'You chose the D option\n";
     break;
   default:
   cout << "Invalid input\n";
}

This piece of code allows a user to type in a single letter - where we don't mind if the input is in upper or lowercase. Not the use of empty conditions for case 'a' and 'd' and no break statement. This allows the case 'A' statement to execute if the user types in an 'A' or an 'a' and the case 'D' statement to execute if the user types in a 'D' or an 'd'.

Another thing to note about the switch statement is that the statements associated with each case are not code blocks but statement sequences. This means you cannot declare a local variable in a statement sequence.
I.e. The following is incorrect:-

switch (ch ) {
   case 1:
      int i;
...

The entire switch statement however is a code block, So you could add a local variable as follows:-

switch (ch ) {
   int i;
   case 1:     
...

If for some reason you were really determined to create a local variable in a case statement sequence, you could cheat:-

switch (ch ) {
   case 1:
      if (1) {    
// this condition is always true
          int i;
          more statements;
      }
...

The last example illustrates the inclusion of an if blocks inside a case statement. You are allowed to include other types of blocks such as if-else blocks, for blocks and of course you can nest switch blocks. Here is an example of nested switch statements.

cout << "Please enter 1 for a pizza or 2 for a drink\n";
cin >> menu;

switch (menu) {
   case 1:
//user selected pizza
      cout << "Press 1 for ham topping, 2 for cheese topping\n";
      cin >> submenu;
     
 switch (submenu) {
          case 1:
             cout >> "pizza with ham topping coming right up\n";
             break;
          
case 2:
             cout >> "pizza with cheese topping coming right up\n";
             break;
       }

      break;

   case 2:
//user selected a drink
      cout << "Press 1 for coke, 2 for orange juice\n";
      cin >> submenu;
      
switch (submenu) {
          case 1:
             cout >> "one coke coming right up\n";
             break;
          case 2:
             cout >> "one orange juice coming right up\n";
             break;
       }

      break;

   default:
//user didn't make a proper selection
      "eel pie and mash coming up\n";
}

~Now try the activity~

Activity 8E

  1. Write a program that allows a user to order a meal which may include one or all of the following, a starter, a main course and a dessert.
    Using the switch statement, work out and display the bill to the user.

You can use these constanst:-

#define STARTER 2.95
#define MAIN_COURSE 6.95
#define DESSERT 1.95


  Extension Work

Carry out the following exercises:-

  1. Now start step8 of the practice assignment 3

That's it!