Previous | Next | Table of Contents | Index | Program List | Copyright

8.4 Data Structures: Hierarchical Records

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
Record Variable Programmer (Type NewEmployee)

Figure 8.2

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.StartDate
references the subrecord StartDate (type Date) of the variable Programmer. The field selector
    Programmer.StartDate.Year
references the Year field of the subrecord Programmer.StartDate. The field selector
    Programmer.Year 
is 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 1985
Procedure Read_Employee_Basic in Program 8.6 can be used to read in a record of type EmployeeBasic.

Program 8.6
Procedure ReadEmployeeBasic

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 ReadEmployee

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.

Exercises for Section 8.4

Self-Check

  1. What must be the type of NewAddress if the following statement is correct?
    Programmer.Home := NewAddress;
    
  2. Write the field selector needed to reference each field described below.

    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

Programming

  1. Write the procedure ReadAdress suggested above.


Previous | Next | Table of Contents | Index | Program List | Copyright

Copyright © 1996 by Addison-Wesley Publishing Company, Inc.