In solving any programming problem, we must select data structures that enable us to represent a variety of different kinds of information efficiently in the computer. The selection of data structures is a very important part of the problem-solving process. The data structures used can have a profound effect on the efficiency and simplicity of the completed program.
The data structuring facilities in Ada are quite powerful and general. In the previous examples, all record fields were scalar types or strings. It is possible to declare a record type with fields that are other structured types. We will call a record type with one or more fields that are record types a hierarchical record.
We began our study of records by introducing a record type
Employee
. In this section we will modify that record by adding new
fields for storage of the employee's address, starting date, and date of birth.
We start with some basic types and constants:
StringLength : CONSTANT Positive := 20; ZipCodeLength : CONSTANT Positive := 5; SUBTYPE IDType IS Positive RANGE 1111..9999; SUBTYPE EmpString IS String(1..StringLength); SUBTYPE ZipString IS String(1..ZipCodeLength); TYPE GenderType IS (Female, Male);Next we a give modified employee record based on that of Section 8.1, and we define an additional record type,
Address
.
TYPE EmployeeBasic IS RECORD ID : IDType; Name : EmpString; Gender : GenderType; NumDepend : Natural; Rate : NonNegFloat; END RECORD; TYPE Address IS RECORD Street : EmpString; City : EmpString; State : EmpString; ZipCode : ZipString; END RECORD;Finally, here is the declaration of the hierarchical record for an employee and a declaration of an employee variable. Notice how simple the employee record is, given the component record types; notice also how we have used the
Date
type provided by the package Dates
developed in
the previous section:
TYPE Employee IS RECORD PayData : Employee; Home : Address; StartDate : Dates.Date; BirthDate : Dates.Date; END RECORD; Programmer: Employee;If
Programmer
is a record variable of type Employee
, the
hierarchical structure of Programmer
can be sketched as shown in
Figure
8.2. This diagram provides a graphic display of the record form. It shows
that Programmer
is a record with fields PayData
,
Home
, StartDate
, and BirthDate
. Each of
these fields is itself a record (called a subrecord of
Programmer
). The fields of each subrecord are indicated under it.
Figure 8.2
Programmer
(Type
NewEmployee
)
To reference a field in this diagram, we must trace a complete path to it starting from the top of the diagram. For example, the field selector
Programmer.StartDatereferences the subrecord
StartDate
(type Date
) of the variable
Programmer
. The field selector
Programmer.StartDate.Yearreferences the
Year
field of the subrecord Programmer.StartDate
.
The field selector
Programmer.Yearis incomplete (which
Year
field?) and would cause a compilation error.
The record copy statement
Programmer.StartDate := DayOfYear;is legal if
DayOfYear
is a record variable of type Date
.
This statement copies each field of DayOfYear
into the
corresponding field of the subrecord Programmer.StartDate
.
The statements
Ada.Text_IO.Put(Item => "Year started: "); Ada.Integer_Text_IO.Put(Item => Programmer.StartDate.Year, Width=>4); Ada.Text_IO.Put(Item => "Month started: "); Ada.Integer_Text_IO.Put(Item => Programmer.StartDate.Month, Width=>4);display two fields of the subrecord
Programmer.StartDate
. The statements
Ada.Text_IO.Put(Item => Programmer.PayData.Name); Ada.Text_IO.Put(Item => "started work in "); Ada.Integer_Text_IO.Put(Item => Programmer.StartDate.Year, Width=>4);display the line
Caryn Jackson started work in 1985Procedure
Read_Employee_Basic
in
Program
8.6 can be used to read in a record of type EmployeeBasic
.
Program 8.6
PROCEDURE Read_Employee_Basic (Item : OUT EmployeeBasic) IS -- Reads one basic employee record into Item. -- Pre : None -- Post: Data are read into record Item. BEGIN -- Read_Employee_Basic Ada.Text_IO.Put(Item => "ID > "); Ada.Integer_Text_IO.Get(Item => Item.ID); Ada.Text_IO.Put(Item => "Name > "); Ada.Text_IO.Get(Item => Item.Name); Ada.Text_IO.Put(Item => "Gender (Female or Male) > "); GenderType_IO.Get(Item => Item.Gender); Ada.Text_IO.Put(Item => "Number of dependents > "); Ada.Integer_Text_IO.Get(Item => Item.NumDepend); Ada.Text_IO.Put(Item => "Hourly rate > "); Ada.Float_Text_IO.Get(Item => Item.Rate); END Read_Employee_Basic;Program 8.7 calls this procedure,
Simple_Dates.Get
, and ReadAddress
(see Programming Exercise 1, below).
Program 8.7
PROCEDURE Read_Employee (Item : OUT Employee) IS -- Reads a record into record variable Item. -- Pre : None -- Post: Reads data into all fields of record Employee. BEGIN -- Read_Employee Read_Employee_Basic (Item.PayData); ReadAddress (Item.Home); SimpleDates.Get (Item.StartDate); SimpleDates.Get (Item.BirthDate) END Read_Employee;The procedure call statement
Read_Employee (Clerk)causes the data read to be stored in record variable
Clerk
. This
procedure uses GenderType_IO
to read the gender of the employee;
GenderType_IO
would need to be defined as an instance of
Ada.Text_IO.Enumeration_IO
.
This example has shown that even though the standard text input/output packages
provide for reading and displaying only a single value at a time, it is easy to
construct an input or display procedure for a simple record type (e.g.,
Simple_Dates.Get
), and to write one for an entire hierarchical
record by calling the simpler ones.
NewAddress
if the following
statement is correct?
Programmer.Home := NewAddress;
a. the programmer's salary
b. the programmer's street address
c. the programmer's month of birth
d. the month the programmer started working
ReadAdress
suggested above.
Copyright © 1996 by Addison-Wesley Publishing Company, Inc.