~ Introduction to Programming: C ~

Session 10 - Counting with the for loop

<<  Back to Contents Page

Session 10 - Counting with the for loop 

In This Session...

In this session we will be covering the following topics:-

Review of Last Session

Last session we covered:-

Counting again - The for loop

We have looked at a few different ways of counting, using a variable to hold the count number.

For example:-

int i=1;

while (i<=10)

{

  printf("i is %d\n",i);

  i++;

}

getch();

will count from 1 to 10. We could have used the following lines in place of i++; which can be read as "increase (or increment) i by 1".

Similary, if we wanted to count from 10 to 1, we may use a snippet of C source code like this:-

int i=10;

while (i>=1)

{

  printf("i is %d\n",i);

  i--;

}

getch();

We could have used the following lines in place of i--; which can be read as decrease (or decrement) i by 1".

Just as the C language has a variation of the if statement in the form of the switch...case statement, there is a special form of the while loop designed specifically for counting. This is called the for command.

The for command is the preferred method of repeating instructions a specific number of times - i.e. by counting using a variable from one number to another. This variable is then often used to assist with the processing within the loop.

For example, to count from 1 to 10:-

int i;



for (i=1; i<=10; i++)

{

  printf("i is %d\n",i);

}

This looks more than a little odd at first sight, and is different to the way languages such as BASIC and Pascal represent the for loop (however other languages such as Perl, C++ and Java use for loops this way too). How does it work?

The for loop has the following structure:-

for (initial value; exit condition; counter) instruction;

or indeed:-

for (initial value; exit condition; counter) {

  instruction1;

  instruction2;

  etc.

}

We set the initial value of the variable that is to be used for counting, in the initial value section - e.g. i=1
We set the condition that checks before the instruction or instructions have been executed, next in the exit condition section - e.g. i<=10. Like the while loop, this tells us the condition that needs to be true in order to execute the statement or statements inside the loop.

Finally, the counter section tells us the calculation to make to increase or decrease the counter after the instructions have been executed but before the condition is re-tested to see whether the loop is to be executed again. E.g. i++ would increase the counter by 1.

You may have spotted that this is the same in effect as:-

initial value;

while (exit condition)

{

  instruction1;

  instruction2;

  ...

  counter;

}

So we can achieve the same effect using a while loop. Why then use a for loop at all?

The advantage is that all of the control processing - i.e. the programming that controls the loop itself - is enclosed in brackets at the beginning of the loop, making it easy to see how the loop will be processed without looking before the loop to see the initial value of the count variable, and the last instruction of the loop to see if the variable is being increased or decreased.

Exercise 37

Create a program using a for loop to count from 10 to 1. Consider what the initial value will be, what the variable must be greater than or equal to in order to execute the instruction (or instructions) in the loop, and whether the variable will be increased or decreased by one.  Place a printf statement inside the loop to display the contents fo the variable used to count myself inside the loop.

Curly brackets

Curly brackets are used to show the beginning and end of a block of source code. It can also be thought of as a list of related instructions grouped together to perform a task.

For example, the main() function which you must have in all of your C programs encloses your entire program with curly brackets - an opening curly bracket { at the beginning directly after the main() declaration, and a closing bracket } at the end of your program. Inside of this block is a list of instructions which comprise the program.

Another example is for for loop. Using curly brackets, you can group together a number of instructions that must be executed each time around the loop.

As a matter of programming style, you should indent (i.e. move to the right by 2-3 spaces) any instructions inside a loop, and line the two curly brackets up so they are in the same column.  This shows you very clearly which closing curly bracket belongs to which opening curly bracket and which instructions are grouped together.  This makes it much easier to follow the function of the program, and helps to prevent forgetting to put in closing curly brackets (probably the most common mistake made in C programming).

If you look back at most of the examples given, you can see how this makes the programs neater and easier-to follow.

It is important to do this in your own programs so that others (including examiners!) - and you - can follow your programs easily.

Exercise 38

Create a program that counts from 1 to 10 using an integer variable called num1 and then puts the message "%d times table\n\n" inside the loop substituting the %d for the contents of the num1 variable.

Put a getch(); command followed by a clrscr(); command before the end of the loop so that you have to press any key after each message to clear the screen carry on with the loop.
The output should look something like this:-

3 times table
 
_
 

Note that only one line will show at a time due to the clrscr(); command.

When you have this working, try this:-

Create a second for loop inside the first. Make sure it comes before the getch() instruction, but after the printf instruction.

Count from 1 to 10 with a variable called num2. At the beginning of the program, go back and declare another new integer variable called result. Multiply num1 by num2 (i.e. num1*num2) and store the result in the result variable. Finally, use a printf statement with three %d modifiers. This should be followed by the list of variables that are to fill the %d modifiers - i.e. num2, num1 and result respectively.

The result should look something like this:-

3 times table
 
1x3=3

2x3=6

3x3=9

...

9x3=27

10x3=30
_
 

This example shows the results of the inner for loop, where the contents of the num1 variable is 3.

You should now have a program that lists each of the times table up to 10, a screenful at a time.

If you have time, try modifying this so that the value 10 is represented by a constant called MAX_TABLE (hint: use the #define directive). Execute the program again to make sure it works as you expect.

Finally, change the value of MAX_TABLE to 15 and execute the program again. Did this work as you expect? Did you substitute MAX_TABLE into both for loops?

This is an example where using a constant allows us to alter a value in two places in our program whilst changing the value in only one location in the program.

If you get stuck with the exercise, there is a solution at the end of the session notes.

Revisiting conditions

You can never recap on conditions enough (honestly!).  This section is not strictly necessary for you to know, but should give you a deeper understanding of how conditions work. Remember that a condition is a test to work out if something is TRUE or FALSE, and is often used to determine control of what gets executed next in a program - e.g. in an if, a while or a for loop.

We'll do a comparison between the use of the 'or' operator (||) and the 'and' operator (&&).  These are both used to join together two separate conditions, but work in different ways.

Rather than give specific examples, we will use a diagram called a 'truth table' to work out what is happening. In a truth table, we put the possible values of one condition agains the possible values of a second condition. A condition (e.g. i==1, j<3, or even j>=i) when you work it through, can only give one of two answers - i.e. either true or false.

Let's take an example - we have a condition (ch!='Y') && (ch!='N'). This is actually two conditions joined together by and AND. So we could represent this as:

condition1 && condition2

where

condition1 is (ch!='Y')

and

condition2 is (ch!='N')

In this case, our '&&' (AND) logic table might look like this:-

Condition 1 (across)
Condition 2 (down)
condition2 TRUE condition2 FALSE
condition1 TRUE True False
condition1 FALSE False False

We can see that the only way that the two conditions will work out to be TRUE is if they both independently work out to be true. Therefore, for the whole condition (ch!='Y') && (ch!='N') to be true, (ch!='Y') must be true, and also (ch!='N') must also be true. Otherwise, the answer must be false. This means if ch does not contain 'Y', it will work out to be TRUE. If ch does not contain N, it will work out to be TRUE. Therefore, the whole condition works out to be TRUE only if ch does not contain Y and it doesn't contain N. If ch was a character put in at the keyboard, then this would work out to be TRUE only if the person pressed neither Y nor N.

How about the OR condition?  Let's take the condition (ch=='Y') || (ch=='N').

If we take this apart, we can again see that it is two expression joined by an 'or' symbol:

condition1 || condition2

where

condition1 is (ch=='Y')

and

condition2 is (ch=='N')

In this case, our '||' (OR) logic table might look like this

Condition 1 (across)
Condition 2 (down)
condition2 TRUE condition2 FALSE
condition1 TRUE True True
condition1 FALSE True False

We can see that the only way that the two conditions will work out to be FALSE is if they both independently work out to be false. Therefore, for the whole condition (ch=='Y') || (ch=='N') to be true, then one of (ch=='Y') or (ch=='N') must also be true (or both of them). Otherwise, the answer must be false. This means if ch contains Y, it will also work out to be TRUE. If ch does contains N, it will work out to be TRUE. However if ch is anything else, neither of these condition is TRUE, therefore the whole condition works out to be FALSE. If ch was a character put in at the keyboard, then this would work out to be TRUE only if the person pressed either Y or N. In this particular case, you would not get the situation where both conditions are TRUE. Can you see why?  This is what is known as an exclusive OR - i.e. where either one condition or the other can be true, but not both simultaneously.

Extra: De Moivres Theorem

These are fundamental laws of logic not just for computers, but also in mathematics.  There are further rules which we need not get into, but in case you are interested, here's a few interesting rules which you can use to simplify complex conditions where you want to reverse the meaning of something - this is known as de Moivre's theorem. This is degree-level stuff, so don't worry if it's a bit too much. You don't really need to know it - it will not be in the exam!:-

c1 and c2 are conditions:-

!(c1&&c2) is the same as (!c1)||(!c2)

!(c1||c2) is the same as (!c1)&&(!c2)

How can we apply this to a sample situation? Just say you wanted to keep a user from proceeding until they have pressed either 'Y' or 'N'.

To proceed, the condition might be (ch=='Y') || (ch=='N')

However, to STOP a person from proceeding (i.e. go back round a loop) we would need to do the opposite of this. Using our theorem, we can reverse the meaning by turning the 'or' into and 'and' and put a 'not' before each individual condition:-

(!(ch=='Y')) && (!(ch=='N'))

Well !(ch=='Y') is the same as saying (ch!='Y') and likewise !(ch=='N') is really (ch!='N')

So our 'reverse meaning' condition becomes:-

(ch!='Y') && (ch!='N')

There we go - how to reverse the meaning of a condition! It all gets more interesting as your conditions become more complex, but it's really best to stay as simple as you can to make your code more readable.

Solution to Exercise 38

Here is a sample solution to Exercise 38, the times table program:-

#include <stdio.h>

#include <conio.h>

#include <ctype.h>



#define MAX_TABLE 10



main()

{
  int num1, num2, result;

  for (num1=1; num1<=MAX_TABLE; num1++)

  {

    printf("%2d times table\n", num1);

    printf("==============\n");



    for (num2=1; num2<=MAX_TABLE; num2++)

    {

      result = num1 * num2;

      printf("%2d x %2d = %3d\n", num2, num1, result);

    }



    getch(); clrscr();

  }

}

And here's a sample screen output:-

 7 times table

==============

 1 x  7 =   7

 2 x  7 =  14

 3 x  7 =  21

 4 x  7 =  28

 5 x  7 =  35

 6 x  7 =  42

 7 x  7 =  49

 8 x  7 =  56

 9 x  7 =  63

10 x  7 =  70

In the Next Session...

In the next session we will be covering the following topics:-

(c) Copyright 2002-4 Simon Huggins.   All Rights Reserved.
If you have any issues or questions regarding the content of this web site, please contact the author by clicking here.
Alternatively, you can leave a voice message on 00 44 (0)7050-618-297 or fax on 00 44 (0)7050-618-298

This Page was last updated: 29 January 2004 13:06