17)

Program 16 - Arrays and global variables
This is really one to get your teeth stuck into

Program 16 Arrays and global variables Source code - prog16.c
This program is another useful program for selecting six lottery ticket numbers at random, a bit like what happens when you select a lucky dip at the newsagent. This may sound a simple program to write at first, but it's not as easy as you would think. The main problem is that the program has to check to see that a number is not selected twice.

The six numbers generated are stored in an array which is declared as a global variable. The numbers display in no order, just the order they were selected for the moment. It is a big program making use of most of what has been done so far, but if it is followed through slowly from the start, it should be possible to understand it.

 

Program code- new parts shown in red

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

#define SELECTIONS 6
#define MAXBALL 49.0
#define MAXRAND 32767

int num[SELECTIONS];

void getnum(int index)
{
float ran;
int i,done=0;

while(done==0)
{
ran=rand();
ran=((ran/MAXRAND)*MAXBALL)+1;
if(ran>MAXBALL)ran=MAXBALL;

num[index]=(int)ran;
done=1;
for(i=0;i<index;i++)
if(
num[index]==num[i])done=0;
}
}

void main(void)
{
int i,done=0;
unsigned char key;

srand(Time());
while(done==0)
{
clrscr();
printf("Your lottery ticket numbers for this week\n\n");
for(i=0;i<SELECTIONS;i++)
{
getnum(i);
printf("%d ",
num[i]);
}
printf("\n\nPress X to exit or any other key to select different numbers\n\n");
key=getch();
if(key=='x'||key=='X')done=1;
}
printf("Good luck, and if you win, please remember me !");
}

 

Description of the program code
Before looking going through the code, arrays will need to be described, as this is the first program that uses one. So far variables have been used to store a single number only, to store more than two numbers, two or more variables have to be declared. Imagine with this system writing a program to store exam results for 1000 students, it would require 1000 variables to be declared. You would probably set about by having lines like int res0001, res0002, res0003 and so on up to res1000; ! While this is possible, it is time consuming and not very practical. It is for this type of thing that arrays are really handy. The line below declares 1000 integer variables that could be used to store the exam results, and the good thing about it is, that it's all in one line !

int res[1000];

In C programming "speak", this declares an array with 1000 elements or indexes, whichever you prefer. The values stored in an array can be set or accessed by using an index in square brackets, eg. res[0], res[1], res[2] .. and so on. The indexes always start at 0 and go through to 1 - the number of elements in the array, in this example the last index that could be used would be 999.

They are used in the same way as variables, so for example to store a mark of 79 for the 1st student you would use the line res[0]=79; To store a mark of 30 for the 25th student you would have the line res[24]=30; ( array index 24 for the 25th element because they start from 0 ). To display the result of the 8th student the line printf("Mark for the 8th student is %d\n",res[7]);

The following code snippet would total up the marks for all 1000 students and display it.

int totalmarks=0;
for(i=0;i<1000;i++)
totalmarks=totalmarks+res[i];
printf("The total marks for all students combined is %d\n",totalmarks);

This snippet uses a for loop to set the variable i going from 0 to 999 ( less than 1000 ), with each loop the students marks are added to the totalmarks variable, which is displayed when the loop finishes.

That's all arrays are; a structure for storing lots of variables of the same data type. What has been described above are single dimension arrays, which are the most common, there are multi-dimension arrays, but these will be covered later when a program crops up that needs to use them, now back to the lottery number selection program above :


The first new line in the lottery program, shown in red int num[SELECTIONS]; declares an array called num which consists of 6 integer elements ( the SELECTIONS constant is set to the value 6 ). The six elements of this array will hold the numbers that the program selects for the ticket. Notice where it has been declared though, at the top of the program, and not inside a function like previous variables. This makes it a global variable which means that every function in the program can access and use it. So far only variables declared within functions have been used. This has meant that, those variables could only be used by the function they were declared in, these are called local variables. It is considered "good programming practice" - again, to limit the use of global variables.


That should be enough information to follow the program through and see how it works, however, because it is a larger program, roughly each line will be described below, starting at the main function :

srand(Time()); As this program is using random number this is needed to set the random seed so that each time the program is run it will generate a different set of numbers, without it, the same numbers would be generated. The function prototype for the srand function is defined in the stdlib.h and the prototype for the Time function is defined in the time.h header file, so these are included at the top of the program.

Next the program enters into a while loop while(done==0) , when the done local variable was declared it was assigned the value 0, so that the program would enter into this loop, because the condition is true. This loop goes around until the user of the program presses the x key, which sets the done variable to 1 making the condition false and hence dropping out of the loop. By having this, the user can press any other key apart from x to select a different random set of 6 numbers.

Within the loop, the program clears the screen clrscr(); and displays some header text printf("Your lottery ticket numbers for this week\n\n");

The six numbers are then selected and displayed by using a for loop for each array index position. for(i=0;i<SELECTIONS;i++) in other words the value of i starts at 0 and goes through to 5 ( less than 6 ).

Within the for loop the getnum function is called and in the process it passes the array index of the number on the ticket the program is selecting, which is held in the i variable and goes from 0 to 5. For now the getnum function can be treated as a black box, the program calls it and when it returns back the number at the position i has been set and is valid. A detailed desription of the function to come...

After the getnum function has been called the program displays the value of the array at the current array index ( held in i again ).

The rest of the main function just checks to see if the x key has been pressed, if not, it goes around again, if it has it sets the done variable and exits the while loop.

The getnum function is where the majority of the work is done and is explained below :

Firstly notice a variable called done is declared, which is local to the getnum function. Even though this has the same name as the variable declared in the main function, the two are totally seperate and not linked in any way at all. The same applies to the i variable as well.

When the function is called, an integer parameter value will be passed to it. The function stores this in the index local variable for the function. The value passed is the value of i in the main function and corresponds to the index position in the array of the number the function is to set.

Another while loop is entered into, this one is needed just in case the function selects a ticket number that has already been selected before. When the the function is sure that the number selected for the ticket at the position index, then it will drop out of the while loop. The bottom part of the function does this and will be explained after the rest of the code.

The ran=rand(); line gets a random number between 0 and 32767 as described in the instructions for the compiler rand() function. The value it gets is stored in the ran variable.

The next line ran=((ran/MAXRAND)*MAXBALL)+1; is the most complex of all the lines in the program. In short it turns the value in ran ( which will be between 0 and 32767 ) into a number between 1 and 50. program 13 showed and explained this is in detail. The only difference here is that constant values have been used in the calculation instead of numbers. The only difference here is that a 1 is added to the end so that the number 0 won't be selected.

The next line, if(ran>MAXBALL)ran=MAXBALL; , is what is called a fudge in programming terms. Reading the documentation, it says that the rand function returns a value between 0 and 32767, I wasn't sure whether the range was inclusive of the two outerbounds or not. If the rand function returns a value of 32767, then this means that it is possible for the function to generate the number 50, which is too high. Just in case this line has been added, so that if this does happen the program will set it back to 49. It does no real harm either way, but is added as a safeguard just in case. Any mathematicians out there will probably cringe at this, because it does mean that the number 49 is more likely to be selected than any other of the 48 numbers. This is only a tiny fractional chance though, and it will do for this purpose.

The next line down num[index]=(int)ran; stores the whole number portion away in the array.

At this point there is no checking done to see if the number that has been selected has already been selected before. If it is the first number to be selected ( index 0 ) then there is no chance that the number has been previously selected, because no other numbers have been selected yet.

The function first of all assumes that the ball hasn't been selected before, by setting the done variable to 1 done=1; The effect of doing this would be to force the function to drop out of the while loop when it reaches the end of the loop.

Assuming is one thing, but the program needs to be certain, so the next lines check the selected number against all the other selections so far, using a for loop and an if statement.

for(i=0;i<index;i++)
if(num[index]==num[i])done=0;

If the first number is being selected then the value of the index variable will be 0, so the program won't process the if line below the for loop. This is because the value of i in the for loop will never be less than index ( 0 ).

If the second number is being selected then the value of the index variable will be 1. This time the for loop will loop from 0 to index-1 ( 0 ). In other words it will execute the if line once with the i value being 0. This will have the affect of saying if(num[1]==num[0])done=0; In other words if the second number just selected is the same as the first number selected then the while loop needs to go around again and select a different number, so the assumption made earlier is not correct.

If the third number is being selected then the value of the index variable will be 2. The i variable will loop from 0 to index -1 ( 1) and the selected number will be checked against the first two selected numbers to make sure that it has not been selected before.

and so on for all 6 numbers....

 

Summary
This page showed how to implement a simple lottery number selection program. Like was said near the beginning, there are 100's, 1000's if not millions of ways of implementing the same program ! This is the way i've done it, but there are loads more ways to do the same thing. This is what programming is, not about knowing what statements do, like printf, scanf etc.. but how to solve problems.

As long as the problem is solved, then it can be considered right and correct, but there are degree's of correctness and different styles of programming though. For a games programmer the right way is the most optimal way of solving a problem, in other words, the way which results in the fastest program. For a scientific based programmer, the correct way is the one which produces the most accurate results.

So far the programs have been about showing the C language, and what each part does and is for. At this point there has been enough information to start thinking about "programming" - problem solving. When you can get to the point of getting a request or specification for a program, for example, "write a lottery number generator", and turning that into something which works, then you are a programmer. This part unfortunately can't be taught :( but by looking at other peoples code and ways of doing things it helps develop a style.

The next page goes on to look at a problem with the program here, and how it can be solved using a known "algorithm" to sort numbers. It doesn't introduce any new C parts but shows a way of sorting the 6 numbers into numerical order using the bubblesort algorithm

 

Tasks

16.1) Assume that the lottery organisers have changed the rules to the game. Now they say, people will be allowed to select 8 numbers and the balls will be numbered from 1 to 59 ! change the program above accordingly so that it will work under the new system ( the advantage of using constants should become a lot clearer ).

 

Go back a page Continue on to next page >>

(c) J.C.Spooner 2001