11 Beginner's Lesson 5: Decision and Control Statements

Greetings,

In Lesson Four we learned how to read input from the keyboard in order
to put data in our programs. This made our programs much more versatile.
In this lesson, we'll be learning several new C statements that have
to do with decision making and program control: if, else, looping,
while, break, and continue. We are learning C by taking things apart
and putting them back together. We can't learn how to program by
just reading, we need to DO IT too! Edit source code --> compile -->
run program --> modify source code in editor --> compile.... etc.

Take the time to key the examples into your computer, and play with
them! Add printf() statements in loops to see what values each
variable contains as the loop repeats (this is a cheap way of
debugging a program on the fly). Change things. Play is a great
way to learn something new. Make sure to try out the exercises
at the end of a lesson... and if there aren't any, make some up!
We would really appreciate it if you'd be kind enough to share
what you're doing with the rest of us! Hey, share your mistakes
and errors with us too. We're all here to learn.

Most computer programs, if they do anything useful at all, execute
their statements using Sequence, Selection, and Interation, or looping.
So far, we've only used Sequence in our programs. The statements are
executed one at a time, in order, from top to bottom, then the program
ends. Decision and control statements allow us to specify the order
in which the statements are to be executed.

We are going to learn how to change the CONTROL FLOW of a program with
BRANCHING statements and LOOPING statements. Branching statements
cause one section of code to be executed or not depending on a
CONDITIONAL CLAUSE. Looping statements are used to repeat a section of
code a number of times or until some condition occurs.

The `if' statement.

The `if' statement allows us to put some decision-making into our
programs. The general form of an `if' statement is:

if (condition)
statement;

If the condition is true (nonzero), the statement will run, otherwise
it won't run. In order to get the condition, we use relational
operators. Here is a table of relational operators:

Relational Operators
====================
Operator | Meaning
------------------------------------
<= | Less than or equal to
< | Less than
> | Greater than
>= | Greater than or equal to
== | Equal
!= | Not equal
------------------------------------

Multiple statements may be grouped by putting them inside curly braces.

if (total <= 0)
{
count++;
printf("You owe nothing.\n");
}

For readability, the statements enclosed in {} are usually indented.
This allows the programmer to easily see which statements are to be
conditionally executed. As we will see later, mistakes in indentation
can result in programs that are misleading and hard to read.

An alternate form of the `if' statement:

if (condition)
statement; /* execute if condition is True */
else
statement; /* execute if condition is False */

If the condition is true, the first statement is executed, otherwise
the second statement is executed.

if (total <= 0)
printf("You owe nothing.\n");
else
printf("You owe %d dollars.\n", amount);

Note to PASCAL programmers: unlike Pascal, C requires you to put
a semi-colon at the end of the statement preceding `else'.

Looping Statements allow the program to repeat a section of code
any number of times or until some condition occurs. If you don't
have a limit on the number of times the loop is supposed to occur,
or if you don't have a condition to satisy, the loop will execute
forever, something to avoid, usually.

The `while' statement.

The general form of the `while' statement is:

while (condition)
statement;

The while statement is used when the program needs to preform
repetitive tasks. The program will repeatedly execute the
statement inside the `while' until the condition becomes FALSE (0).
If the condition is initially false, the statement will not execute
at all.

This next program will compute all the fibonaci numbers that are
less than 100.

#include <stdio.h>
int main(void)
{
int old_number; /* previous Fibonacci number */
int current_number; /* current Fibonacci number */
int next_number; /* next number in the series */

/* start things out */
old_number = 1;
current_number = 1;
printf("1\n"); /* print first number */

while (current_number < 100)
{
printf("%d\n", current_number);
next_number = current_number + old_number;

old_number = current_number;
current_number = next_number;
}
return 0;
}

A Fibonacci series develop by adding the previous two numbers to
get the next number, ad infinitum... so it looks like this:

0 1 1 2 3 5 8 13 21 34 ...

In general terms this is: fn = f(n-1) + f(n-2)

Mathematicians use this very terse style of naming variables. In the
above program, the variables were renamed:

fn => next_number
f(n-1) => current_number
f(n-2) => old_number

We want to loop until our current term is 100 or larger. The `while'
loop: while (current_number < 100) will repeat our computation
and printing until we reach this limit.

The `break' statement.

Loops can be exited at any point throught the use of a `break'
statement. Suppose we want to add a series of numbers, but we
don't know how many numbers are to be added together? We need
some way of letting the program know we have reached the end of
our list. In the next program, we use the number zero (0) to
signal the end of the list:

#include <stdio.h>
int main(void)
{
char line[100]; /* line for data input */
int total; /* running total of numbers */
int item; /* next item to add to list */

total = 0;
while (1)
{
printf("Enter # to add\n");
printf(" or 0 to stop: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &item);
if (item == 0)
break;
total += item;
printf(Total: %d\n", total);
}
printf("Final total %d\n", total);
return (0);
}

In the above program, because the `while' statement is while (1)
the only way to break out of the loop is with a `break' statement.

The `continue' statement.

The `continue' statement, when executed, starts executing the body
of the loop over again from the top. For example, if we wanted to
modify the last program to total only numbers greater than zero,
we could write a program like this:

#include <stdio.h>
int main(void)
{
char line[100]; /* line for data input */
int total; /* running total of numbers */
int item; /* next item to add to list */
int minus_items /* number of negative items */

total = 0;
minus_items = 0;
while (1)
{
printf("Enter # to add\n");
printf(" or 0 to stop: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &item);
if (item == 0)
break;
if (item < 0)
{
minus_items++;
continue;
}
total += item;
printf(Total: %d\n", total);
}
printf("Final total %d\n", total);
return (0);
}

The Assignment Anywhere Side Effect.

C allows the use of assignment statements almost anywhere. You can
even put assignment statements inside another assignment statement!

/* Please don't program like this */
average = total_value / (number_entries = last - first);

This is the same as saying:

/* Please program like this */
number_entries = last - first;
average = total_value / number_entries;

C also allows you to put an assignment in the while conditional.

/* Please don't program like this */
while ((current_number = last_number + old_number) < 100)
printf("Term %d\n", current_number);

Notice how much clearer the logic is in the following?

/* Please program like this */
while (1)
{
current_number = last_number + old_number;
if (current_number >= 100)
break;
printf("Term %d\n", current_number);
}

Debugging exercise:

/*
For some reason, this program thinks that everyone
owes a balance of 0 dollars. Why?
*/
#include <stdio.h>
int main(void)
{
char line[80]; /* input line */
int balance_owed; /* amount owed */

printf("Enter number of dollars owed: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &balance_owed);

if (balance_owed = 0)
printf("You owe nothing.\n);
else
printf("You owe %d dollars.\n", balance_owed);

return 0;
}

Here are some exercises to play with.

1. Write a program to find the distance between to points.

2. A professor generates letter grades using the following table:

% Correct | Grade
----------+------
0-60 | F
61-70 | D
71-80 | C Given a numeric grade, print the letter.
81-90 | B
91-100 | A
----------+------

3. Modify the previous program to print out a + or - after
the letter grade based on the last digit of the score.

Last Digit | Modifier
-----------+---------
1-3 | - For example 81=B-, 94=A, 68=D+.
4-7 | <blank> An F is only an F, no F+ or F-.
8-0 | +
-----------+---------

NOTE: Programmers frequently have to modify code that someone
else wrote. A good exercise is to take someone else's, such as
the program for exercise 2, and modify it. How could we facilitate
something like this online, in this "course"? Suggestions?

4. Given an amount (less than $1.00), compute the number of
quarters, dimes, nickels, and pennies needed. Use your local
currancy if you're not in America, or are not familiar with
the dollar and change.

5. A leap year is any year divisible by 4 unless it is divisible
by 100, but not 400. Write a program to tell if a year is a leap year.

6. Write a program that, given the number of hours an employee worked,
and the hourly wage, computes the employee's weekly pay. Count any
hours over forty as overtime at time and a half.

This should keep us busy for awhile? 8^D

Happy Programming!
--
K