The if / else Structure

First off, before typing this code into the BeIDE, I will show you a useful technique for debugging simple programs and smaller functions. My professor described it as a hand-simulation. There is an official name for it, but, unfortunately, I cannot remember it.

There is a lot of good meat in this lesson. There are some tips and tricks to C++ coding, as well as the lesson at hand. Do the simulation first, so you will spend some more time thinking on this one, and get a better understanding of it in its entirety. Trust me, you'll feel much better (i.e., confident) by the end of this page. :)

After you have done the hand simulation of this code, type it in, compile it and run it to check yourself. Name all project files "ifelse.*".

Simulate the following code:


#include <iostream>

int main()
{
   int alpha = 3;
   int beta = 8;
   int gamma = 6;
   int delta = 2;
   int chi = 4;
   int zeta = 9;
   
   if (alpha <= beta)
      alpha--;
   
   if (gamma > delta)
      gamma += 2;
   else gamma -= 3;
   
   if (chi == zeta)
   {
      chi *= 2;
      zeta *= 2;
    }
    else if (chi < zeta)
    {
       chi /= 2;
       zeta /= 2;
     }
     else 
        chi = 0;
     
     cout << alpha << beta << gamma << delta << chi << zeta << endl;
     
     return 0;
} 

To simulate the above code, you are going to walk through the code, line by line, and write the actions of the program down onto a piece of paper, just like the program would do while it is executing. Let's start with the first lines:

#include <iostream>
int main()
{

These you do not need to worry about, they are behind the scenes, as far as hand-simulations go. Just know that we are beginning our simulation at the first line of the main function:

   int alpha = 3;

To simulate this, we must first determine what is happening here. We are defining an integer, naming it alpha, and storing the value 3 into it. When this happens, the compiler will allocate space in memory for an integer, label this space as "alpha", and then give it the value of 3. To simulate this on paper, first draw a square (allocating a memory space for an integer. Then write the name of the variable next to the square, (to the left or below, preferably, as things can get messy with larger amounts of variables and changes to them). This simulates naming that space. Lastly, we write the number 3 into the square "memory location" that we drew. This is simulating giving the value of 3 to that variable.

Now repeat this for the rest of the definitions:

   int beta = 8;
   int gamma = 6;
   int delta = 2;
   int chi = 4;
   int zeta = 9;

Now we are on to the next line in the program:

   if (alpha <= beta)

If alpha is less than or equal to beta... Look at your simulation, alpha is 3, beta is 8. If 3 <= 8 - this conditional expression evaluates to true, as 3 is less than (or equal to) 8. We now simulate the next line of code, as the compiler would do as well.

      alpha--;

Whoa! What's that? There are many C++ "tricks" that shorten commonly used lines of code. This line of code is the same as:

     alpha = alpha - 1 ;

or even:

     alpha -= 1 ;  // ( alpha becomes itself minus 1 - more on this in a minute )

Much easier to type, is it not? We have used the decrementing unary operator (--). Notice its position in relation to the variable, this is important. What you have now used is the post-decrement unary operator. There are two types of unary operators like this, increment and decrement ( ++ and -- , respectively). There are two ways to apply each, pre- and post-. In this example, the post-decrement unary operator does its action at the end of evaluating the statement. The pre-[operator] would perform its action prior to evaluating the statement. The difference has no effect on this statement, but you will see an example later that the position of the operator will have a significant effect.

We are going to get sidetracked now on another C++ shortcut. +=, -=, *= and /= are all used in this program. These are known as assignment operators. Sound familiar? That's because = is also an assignment operator. Remember (I cannot stress this enough), the difference between = and == ! Your assignment operators are as follows:

=      +=     -=     *=    /=     %=

The assignment operator assigns the value that is on the right of the operator to what is on the left of the operator. But only in the first case (=) does it do so traditionally. When you have an assignment operator that is one of the others, it will take the value stored in the variable on its' left, evaluate it as designated, and store the new value into the same variable. I'll use the earlier alpha statement for example.

     alpha -= 1 ;

This is just a shortcut for writing

     alpha = alpha - 1 ;

Now taking something and subtracting 1 from it is obviously better with the decrementing unary operator described earlier. But what if you wanted to subtract other numbers? This is the shortcut for you then. The other operators work the same way.

     alpha *= 5 ;

Alpha becomes itself multiplied times 5. If alpha was 3, then alpha becomes 15, (3 x 5).

To end this tangent and get back to your simulation, here is the code again, just as a reminder so you do not have to scroll back up to find it:

   if (alpha <= beta)
      alpha--;

The conditional expression was true, as you determined earlier. Because of this, you must execute the next statement, which, in essence, was minus one from alpha. Cross out (or erase) the previous value of alpha (3), and replace it with the new value, which evaluates to 2. Because alpha (3) - 1 = 2. The variable alpha must now show in your square as 2, as it would in memory.

To summarize what has just happened here, you have determined that because alpha was less than beta, alpha is decremented by one. Or: if alpha (3) is less than or equal to beta (8), which it is (true), then decrement alpha by 1, making it now have the value of 2. Please note, I used the word then, in this sentence. Do NOT use then when coding if statements - this is not BASIC.

Now we will look at an if / else statement:

   if (gamma > delta)
      gamma += 2;
   else gamma -= 3;

In pseudo-code: If gamma is greater than delta, then gamma becomes itself plus 2; else (OTHERWISE) gamma becomes itself minus 3.

Notice I emphasised OTHERWISE rather than else in the pseudocode. If the if statement is true, the following statement is evaluated. If the if statement is evaluated as false - do the else statement. The if statement is the controlling factor, and it cannot be both true and false at the same time, and therefore only one or the other following statements will be executed - never both.

Back to the hand simulation. Gamma is 6 and delta is 2. If gamma is greater than delta - true, then gamma becomes itself plus 2 = 8. Else - there is no else - the conditional expression was true! Make the change to gamma on your hand simulation.

Next:

   if (chi == zeta)
   {
      chi *= 2;
      zeta *= 2;
    }
    else if (chi < zeta)
    {
       chi /= 2;
       zeta /= 2;
     }
     else 
        chi = 0;

This is a big code fragment, but look at it in three parts. There is the if conditional expression, and if that is not met (i.e., false) you move on to the else if conditional expression, AND if that is not meet, you move on to the else statement. Now remember I said during the previous lesson we would see how to execute more than one statement within the if structure's syntax for only one statement, well there it was, twice. In pseudocode, this basic structure would essentially look like this:

   if (this is true)
        [do this]
   else if (this is true)
        [do this]
   else // if none of the above evaluated true
        [do this]

You still can only have one of the [do this] statements execute, as only one conditional expression will be meet as true. This is because the program will skip the remaining conditional expressions once one conditional expression is met, which is more optimal for speed if you know that your program only needs to find one true conditional expression. If you want to have the program evaluate each and every one of your if conditional expressions, do not use the if / else if / else structure, use the if structure in repetition in the same way as the last lesson. The executing program will evaluate each and every if statement. But it will not evaluate any else if or else statements once a conditional expression is evaluated as true and the following statement has been executed.

With curly-braces around multiple statements within the structure -

   if (chi == zeta)
   {
      chi *= 2;
      zeta *= 2;
    }

the program will act as though everything within those curly-braces is one statement after the conditional expression. Just as the compiler knows that everything in the main function resides as one program between the main's curly-braces, it knows that everything following the if conditional expression that is within curly-braces is one statement as far as the if conditional expression is concerned. Note that if this mistake was made:

    else if (chi < zeta)
        chi /= 2;
        zeta /= 2;
    else 
        chi = 0;

you would have a problem, because the following statement after the else if conditional expression has one statement, chi /= 2; , but then has ANOTHER statement, zeta /= 2; , immediately following, before the last else statement. The compiler will see an ended else if statement:

    else if (chi < zeta)
        chi /= 2;

another statement it thinks is unrelated:

        zeta /= 2;

and then an else statement without an if to begin it.

    else 
        chi = 0;

The structure has been broken, and so is the program. Just remember, only ONE statement per conditional expression, OR use curly-braces to make it one statement.

Now let's analyze what is happening here:

   if (chi == zeta)        // if chi (4) is equal to zeta (9) ---- no this evaluates to false
   {                       // do NOT execute this statement
      chi *= 2;
      zeta *= 2;
    }
    else if (chi < zeta)   // else if chi (4) is less than zeta (9)  ---- true
    {                      // do this segment between the curly-braces
       chi /= 2;           //  chi becomes chi divided by (/) 2 , 4 / 2 equals 2
       zeta /= 2;          // zeta becomes zeta divided by 2 , 9 / 2 equals 4
                           // remember the rules of dividing integers
                           // they drop any fractional leftovers because zeta is an integer.
     }                     // end this statement
     else                  // else nothing, the conditional expression has already been met.
        chi = 0;

Annotate, line by line, what has happened in memory (on your paper). You should do this as you read each line of code.

And back to some familiarity:

     
     cout << alpha << beta << gamma << delta << chi << zeta << endl;
     
     return 0;
} 

To hand-simulate this, draw a screen (large square) somewhere on your paper and write down the output, just like a screen would display. Remember, you didn't code any whitespace in between the numbers, so they will all run-on together.

Now, type this code into BeIDE, and run it. Did your hand simulation come out with the same numbers?

Now, before going on to the next page, solve this problem:

Take the following code fragment (from the last lesson) and write a program that uses a if / else if / else structure to better optimize the code.

   if (weight <= 0 || weight > 500)
      cout << "You are a liar!" << endl;
   if (weight > 0 && weight < 50)
      cout << "Eat more!" << endl;
   if (weight >= 50 && weight < 100)
      cout << "I hope you are short! " << endl;
   if (weight >= 100 && weight < 200)
      cout << "Quite Average." << endl;
   if (weight >= 200 && weight < 300)
      cout << "I hope you are tall." << endl;
   if (weight >= 300 && weight <= 500)
      cout << "Into sumo?"  << endl;

After you have successfully compiled and run that one, take your break, because afterwards, we are going to get into looping structures!