Objects First


Using boolean expressions - Branching statements

C programs are written as a sequence of statements which are executed in the order in which they are written.

S1; S2; S3; ...

Statement S1 is executed first, followed by S2, then S3, etc.

However, we often need to choose different sets of operations depending on the data. For instance, your bank's computer, when presented with a withdrawal request, will act in a markedly different manner if you have enough funds to cover the request from that if your request exceeds your available funds! To accomplish this, we have branching statements. These alter the flow of control in a program.

The most common of these is the if .. else .. statement.

Formally, it looks like this:

if( expression ) statement;
[ else statement; ]

where the brackets [ and ] indicate that the else part is optional.

Thus we could write:

if ( withdrawal_amount <= balance ) {
    process_withdrawal( withdrawal_amount );
    }
else {
    printf("Insufficient funds!\n");
    }

Note that statement can mean

In the above example, since there is only one statement in each "branch", we could have written:
if ( withdrawal_amount <= balance )
    process_withdrawal( withdrawal_amount );
else printf("Insufficient funds!\n");
but that I have chosen to include the braces anyway.

Style note

I recommend that you include the braces whether they are needed or not. This makes later editing of the program less susceptible to errors.

Nested if statements

if statements can be nested. For example, suppose we want a method that will tell us whether a rectangle has an area that is between two limits. Given a rectangle object and two limits - one lower and the other higher, we want this method to tell us whether the rectangle lies within the limits by returning a true if it is, and a false if it's not. Remember that C doesn't have a boolean type, so we make this method return an int. The full specification is:

int AreaWithinLimits( Rectangle r, int lower, int upper );

and the implementation might look like this:

#include "Boolean.h"

int AreaWithinLimits( Rectangle r, int lower, int upper ) {
    if ( Area(r) < lower ) {
        return FALSE;
        }
    else {
        if ( Area(r) > higher ) return FALSE;
        else return TRUE;
        }
    }
Note that this assumes that we've defined two constants in Boolean.h:
#define TRUE    1
#define FALSE   0
However, although this will work fine, we can make it simpler!
int AreaWithinLimits( Rectangle r, int lower, int upper ) {
    if ( (Area(r) < lower) || (Area(r) > higher) ) {
        return FALSE;
        }
    else {
        return TRUE;
        }
    }
Here, we've used the fact that an if statement takes any expression and combined two tests into one expression, linking the two conditions by the logical or operator, ||. Note the double vertical bars of the logical or operator - not the single vertical bar of the arithmetic or operator.

This is another trap for new (and old!) C programmers -
just like the problem with ==.

Both

if ( (Area(r) < lower) || (Area(r) > higher) )

and

if ( (Area(r) < lower) | (Area(r) > higher) )

are perfectly legal C expressions - so the compiler can't warn you that you made a mistake.

Be careful with all logical expressions -
the 3 logical operators (==, &&, ||)
all have double symbols.

Further enhancements

In fact, we can make it even simpler, by noting that a simple return statement followed by an expression will do!
int AreaWithinLimits( Rectangle r, int lower, int upper ) {
    return ( (Area(r) >= lower) && (Area(r) <= higher) );
    }

Dangling "else"

We can obviously make our conditional statements as complex as we like. An if statement is a statement itself, so that either branch of an if statement can itself be a conditional statement. This leads to some potential for confusion. If I had written this:
int AreaWithinLimits( Rectangle r, int lower, int upper ) {
    if ( Area(r) < lower ) return FALSE;
    else
    if ( Area(r) > higher ) return FALSE;
    else return TRUE;
    }

To which if does the second else belong? The standard specifies that it belongs to the immediately preceding if.

Style note

This is just another reason for using the braces whether they are needed or not.
It saves anyone (you while writing the program and anyone following you while reading it) from needing to remember this rule!

Key terms

branching statements
Statements which alter normal sequential statement execution and cause a "jump" to a statement which doesn't follow the current one. if, switch and function calls are all branching statements.
flow of control
The order in which statements are executed in a program: envision a pointer which indicates the next statement to be executed moving or flowing from one statement to the next.

Continue on to The character class Back to the Table of Contents
© John Morris, 1998