home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
m2t-1.zip
/
CHAP11.TXT
< prev
next >
Wrap
Text File
|
1989-01-18
|
19KB
|
412 lines
Chapter 11
RECORDS
PREREQUISITES FOR THIS MATERIAL
______________________________________________________________
In order to do a profitable study of this material, you will
need a good understanding of all of the material in Part I.
The material concerning the scalar type from chapter 11 is
also needed.
We come to the grandaddy of all data ================
structures in Modula-2, the record. A SMALLREC.MOD
record is composed of a number of ================
variables any of which can be of any
predefined data type, including other records. Rather than
spend time trying to define a record in detail, lets go right
to the first example program, SMALLREC.MOD. This is a program
using nonsense data that will illustrate the use of a record.
A VERY SIMPLE RECORD
______________________________________________________________
There is only one entry in the type declaration part of the
program, namely the record identified by Description. The
record is composed of three fields, the Year, Model, and
Engine variables. Notice that the three fields are each of
a different type, indicating that the record can be of mixed
types. You have a complete example of the way a record type
is defined before you. It is composed of the identifier
Description, the reserved word RECORD, the list of elements,
and followed by END;. Notice that this only defines a type,
it does not define any variables. That is done in the var
declaration where the variable Truck is defined as a record
variable of type Description. The variable Truck has three
components, Year, Model, and Engine, and any or all of these
components can be used to store data pertaining to the
variable named Truck.
An array of 10 Cars is also defined in line 13 for later use.
In order to assign values to the various fields, the variable
name is followed by the sub-field with a separating period.
Keep in mind that Truck is a complete record containing three
variables, and to assign or use one of the variables, you must
designate which sub-field you are interested in. Examine the
program where the three fields are assigned meaningless data
for illustration in lines 18 through 20. Notice that each of
the components is treated as a simple variable and each
component is assigned some nonsense data for illustration.
Study the dot notation carefully here because it will be used
frequently in Modula-2 programs.
11-1
Chapter 11 - Records
The loop in lines 22 through 26 is used to assign nonsense
data to all of the fields of the array of record variables
named Cars. The Year field is assigned an integer number
varying with the subscript, all Model fields are assigned the
name Duesenburg, and all Engine variables are assigned the
value V8. In order to further illustrate that there are
actually 30 variables in use here, a few are changed at random
in the next few statements, being very careful to maintain the
required types as defined in the type declaration part of the
program.
The Truck variable is printed out for illustration and
finally, all ten composite variables named Cars, consisting
of 30 actual variables in a logical grouping are printed out
using the same "var.subfield" notation described above. If
the preceding description of a record is not clear in your
mind, review it very carefully. It's a very important concept
in Modula-2, and you won't have a hope of a chance of
understanding the next example until this one is clear. Keep
in mind that a record is used to group some number of possibly
different types of data that are related to each other in some
way.
A SUPER RECORD
______________________________________________________________
Examine the example file BIGREC.MOD for a ================
very interesting record. First we have a BIGREC.MOD
constant defined. Ignore it for the ================
moment, we will come back to it later.
Within the type declaration we have three records defined, and
upon close examination, you will notice that the first two
records are included as part of the definition of the third
record. The record identified as Person actually contains 8
variable definitions, three within the FullName record, two
of its own, and three within the Date record. Once again,
this is a type declaration and does not actually define any
variables. The actual variables will be defined in the var
part of the program.
The var part of the program defines some variables beginning
with the array of Friend containing 50 (because of the
constant definition in the const part) records of Person.
Since Person defines 8 fields, we have now defined 8 times 50
= 400 separate and distinct variables. Each of the 400
separate variables has its own type associated with it, and
the compiler will generate an error if you try to assign any
of those variables the wrong type of data. Since Person is
a type definition, it can be used to define more than one
variable, and in fact it is used again to define three more
records, Self, Mother, and Father. These three records are
each composed of 8 variables, so we have 24 more variables
11-2
Chapter 11 - Records
which we can manipulate within the program. Finally we have
the variable Index defined as a simple cardinal type variable.
Notice that if we desired, we could also define a variable of
type FullName composed of 3 simple variables.
HOW TO MANIPULATE ALL OF THAT DATA
______________________________________________________________
In the program we begin by assigning data to all of the fields
of Self in lines 30 through 42. Examining the first three
statements of the main program, we see the construction we
learned in the last example program being used, namely the
period between descriptor fields. The main record is named
Self, and we are interested in the first part of it, namely
the Name part of the person record. Since the Name part of
the person record is itself composed of three parts, we must
designate which part of it we are interested in. The name
Self.Name.FirstName is the complete description of the first
name of Self and is the first assignment statement which is
assigned the name of Charley. The next two fields are handled
in the same way and should be self explanatory.
WHAT IS THE WITH STATEMENT?
______________________________________________________________
Continuing on to the fourth field, the City, there are only
two levels required because City is not another record
definition. The fourth field is therefore completely defined
by Self.City. Notice the "WITH Self DO" statement. This is
a shorthand notation used with record definitions to simplify
coding used in the same manner as in Pascal. From the next
statement to the matching end statement in line 42, any
variables within the Self record are used as though they had
a Self. in front of them. It greatly simplifies coding to be
able to omit the leading identifier within the with section
of code. You will see that City, and State, are easily
assigned values without further reference to the Self
variable. When we get to the Day part of the birthday, we are
back to three levels and the complete definition is
Self.Birthday.Day but once again, the Self part is taken care
of automatically because we are still within the "WITH Self
DO" area.
To illustrate the with statement further, another is
introduced, "WITH Birthday DO", which takes effect until the
end statement. Within this area both leading identifiers are
handled automatically to simplify coding, and Month is
equivalent to writing Self.Birthday.Month if both with
statements were removed. You may be wondering how many levels
of nesting are allowed in record definitions. There doesn't
appear to be a limit according to the Modula-2 definition, but
we do get a hint at how far it is possible to go. In most
11-3
Chapter 11 - Records
implementations of Modula-2, you are allowed to have with
statements nested to nine levels, and it would be worthless
to nest with statements deeper than the level of record
nesting. Any program requiring more levels than nine is
probably far beyond the scope of your programming ability, and
mine, for a long time.
After assigning a value to the year, the entire record of Self
is defined, all eight variables.
SUPER-ASSIGNMENT STATEMENTS
______________________________________________________________
The next statement, Mother := Self; is very interesting.
Since both of these are records, both are the same type of
record, and both therefore contain 8 variables, Modula-2 is
smart enough to recognize that, and assign all eight values
contained in Self to the corresponding variables of Mother.
So after one statement, Mother is completely defined. The
next statement assigns the same values to the eight respective
fields of Father, and the loop in lines 47 through 50 assigns
all 50 Friend variables the same data. We have therefore
generated 400 + 24 = 424 separate pieces of data so far in
this program. We could print it all out, but since it is
nonsense data, it would only waste time and paper. Lines 51
through 56 write out three sample pieces of the data for your
inspection.
WHAT GOOD IS ALL OF THIS
______________________________________________________________
It should be obvious to you that what this program does, even
though the data is nonsense, appears to be the beginning of
a database management program, which indeed it is. It is a
crude beginning, and has a long way to go to be useful, but
you should see a seed for a useful program.
Now to go back to the const as promised. The number of
friends was defined as 50 and used for the size of the array
and in the assignment loop near the end of the program. You
can now edit this number and see how big this database can
become on your computer. Your compiler should be capable of
storing about 1000 records even within the smallest model
available on any compiler. If your compiler uses a larger
memory model, you will be able to store significantly more
records. See how big you can make the number of friends
before you get the memory overflow message. Keep the number
in mind because when we get to the chapter on Pointers and
Dynamic Allocation, you should see a marked increase in
allowable size, especially if you have a large amount of RAM
11-4
Chapter 11 - Records
installed in your computer. If your compiler uses a large
memory model, you won't see an increase in size but it will
be an interesting exercise anyway.
A VARIANT RECORD
______________________________________________________________
If any part of this chapter is still unclear, it would be good
for you to go back and review it at this time. The next
example will really tax your mind to completely understand it,
especially if the prior material is not clear.
Examine the program VARREC.MOD for an ================
example of a program with a variant record VARREC.MOD
definition. In this example, we first ================
define a scalar type, namely KindOfVehicle
for use within the record. Then we have a record defining
Vehicle, intended to define several different types of
vehicles, each with different kinds of data. It would be
possible to define all variables for all types of vehicles,
but it would be a waste of storage space to define the number
of tires for a boat, or the number of propeller blades used
on a car or truck. The variant record lets us define the data
precisely for each vehicle without wasting data storage space.
WHAT IS A TAG-FIELD?
______________________________________________________________
In the record definition we have the usual record header
followed by three variables defined in the same manner as the
records in the last two example programs. Then we come to the
case statement. Following this statement, the record is
different for each of the four types defined in the associated
scalar definition. The variable WhatKind is called the
tag-field and must be defined as a scalar type prior to the
record definition. The tag-field selects the variant used,
when the program uses one of the variables with this record
type. The tag-field is followed by a colon and its type
definition, then the reserved word OF. A list of the variants
is then given, with each of the variants having the variables
for its particular case defined. The list of variables for
one variant is called the field list.
A few rules are in order at this point. The variants do not
have to have the same number of variables in each field list,
and in fact, one or more of the variants may have no variables
at all in its variant part. If a variant has no variables,
it must still be defined with a blank followed by a
semi-colon. All variables in the entire variant part must
have unique names. The three variables, Wheels, Tires, and
Tyres, all mean the same thing to the user, but they must be
different for the compiler. You may use the same identifiers
11-5
Chapter 11 - Records
again in other records and for simple variables anywhere else
in the program. The Modula-2 compiler can tell which variable
you mean by its context. Using the same variable name should
be discouraged as bad programming practice because it may
confuse you or another person trying to understand your
program at a later date.
USING THE VARIANT RECORD
______________________________________________________________
We properly define four variables with the record type Vehicle
and go on to examine the program itself.
We begin by defining one of our variables of type Vehicle,
namely the variable named Ford. The seven lines assigning
values to Ford are similar to the prior examples with the
exception of the fourth line. In the fourth line the
tag-field which selects the particular variant used is set
equal to the value Truck, which is a scalar definition, not
a variable. This means that the variables named Motor, Tires,
and Payload are available for use with the record Ford, but
the variables named Wheels, Engine, Tyres, etc. are not
available in the record named Ford.
Next, let's define the record Sunfish as a boat, and define
all of its variables. All of sunfish's variables are defined
but in a rather random order to illustrate that they need not
be defined in a particular order. Recall the use of with from
the last example program.
To go even further in randomly assigning the variables to a
record, we redefine Ford as having an Engine which it can only
have if it is a car. This is one of the fine points of the
record. If you assign any of the variant variables, the
record is changed to that variant, but it is the programmers
responsibility to assign the correct tag-field to the record,
not the Modula-2 compiler's. Good programming practice would
be to assign the tag-field before assigning any of the variant
variables. The remainder of the Ford variables are assigned
to complete that record, the non-variant part remaining from
the last assignment.
The variable named Mac is now assigned the value of the
variable Sunfish. All variables within the record are copied
to Mac including the tag-field, making Mac a boat.
NOW TO SEE WHAT WE HAVE IN THE RECORDS
______________________________________________________________
We have assigned Ford to be a car, and two boats exist, namely
Sunfish and Mac. Since Schwinn was never defined, it has no
data in it, and is at this point useless. The Ford tag-field
11-6
Chapter 11 - Records
has been defined as a car, so it should be true in the if
statement in line 54, and the first message should print. The
Sunfish is not a bicycle, so the statement in line 63 will not
print. The Mac has been defined as a boat in the single
assignment statement, so it will print a message with an
indication that all of the data in the record was transferred
to its variables.
Even though we can make assignment statements with records,
they cannot be used in any mathematical operations such as
addition, or multiplication. They are simply used for data
storage. It is true however, that the individual elements in
a record can be used in any mathematical statements legal for
their respective types.
One other point should be mentioned. The tag-field can be
completely eliminated resulting in a "free union" variant
record. This is possible because Modula-2, as you may
remember from above, will automatically assign the variant
required when you assign data to one of the variables within
a variant. This is the reason that all variables within any
of the variants must have unique names. The free union record
should be avoided in your early programming efforts because
you cannot test a record to see what variant it has been
assigned to.
A NOTE TO PASCAL PROGRAMMERS
______________________________________________________________
A record with a free union variant is commonly used in Pascal
to do type transfers, but this should be discouraged in
Modula-2 since it has a complete set of carefully defined type
transfer functions for that purpose. In addition, the method
of data storage is not specified as a part of the language and
a free union would not operate the same way with different
compilers if used for the purpose of type transfer.
PROGRAMMING EXERCISE
______________________________________________________________
1. Write a simple program with a record to store the names
of five of your friends and display the names.
11-7