4.8 Record Types

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

A record type declaration specifies a set of components that may have different types. Each component has its own name and can be accessed separately from the other components. Two kinds of record types are: those without discriminants and those with discriminants. (In the former case all objects have the same kinds of components.)

Declarations of Record Types without Discriminants

General Form
type R_Type is
  record
    Component_1 : Type_1;
    Component_2 : Type_2;
    Component_3 : Type_3;
    -- etc
  end record;
Example
type Employee_Record is
  record
    Name           : String_25;
    Year_Hired     : Ada.Calendar.Year_Number;
    Monthly_Salary : Float;
  end record;
  -- where type String_25 is array (1..25) of Character;

A discriminated record type includes one or more special elements, called discriminants, that are used to parameterize the declaration. Their effects are felt during elaboration-time or execution-time. They can be used, for example, to specify an array length within one component or the existence of other components called variants.When a record type with discriminants does not include default values for its components, it is known as an indefinite subtype. When variants are present, a case-like structure is part of the record type declaration. Record types with discriminants and variants are known as variant records.

Declarations of Record Types with Discriminants

General Form without Variants
type DR_Type is (discriminant_part)
  record
    Component_1 : Type_1;
    Component_2 : Type_2;
    Component_3 : Type_3;
    -- etc
  end record;
  -- where the discriminant_part is a list of the
  -- form: (X : X_Type, Y : Y_Type, etc)
  -- where X and Y appear in Type_1, Type_2, etc
General Form with Variants
type DRV_Type is (discriminant_part)
  record
    Component_A : Type_A;
    Component_B : Type_B;
    Component_C : Type_C;
    -- etc
    case XorY is
      when X =>
        Component_X : Type_X;
      when Y => 
        Component_Y : Type_Y;
    end case;
  end record;

Example Program Illustrating Record Types 

This program has two new packages: one that declares a record type called Batting_Record and exports two functions for computing averages, and one that exports a Display_Averages procedure while it encapsulates an object, BA, that contains an array of record objects of type Batting_Record. The latter depends upon the former as well as upon Ada.Text_IO. Note the use type clause.

Im4-9.gif (6095 bytes)

Note several explicit conversions in the functions that compute batting average and slugging average.

Source Code Listing

-----------------------------------------------------------
--------------------  Batting_Averages --------------------
--  This package exports a record type holding the batting 
--  data for a specific player in a specific year, a fixed-
--  point type and two functions. The functions are used 
--  for computing batting average (Hits per At_Bats) and
--  slugging average (Total_Bases per At_Bats). 
-----------------------------------------------------------
package Batting_Averages is
      
  type String_14 is array (1..14) of Character;
    
  type Batting_Record is           -- start record type declaration
    record
      Name      : String_14;
      Year      : Natural;
      At_Bats   : Natural;
      Singles   : Natural;
      Doubles   : Natural;
      Triples   : Natural;
      Home_Runs : Natural;
    end record;                    -- finish declaration
  
  type Batting_Average_Type is delta 0.001 range 0.000 .. 4.000;
  
  function Batting_Average(BR : Batting_Record)
           return Batting_Average_Type;
           
  function Slugging_Average(BR : Batting_Record)
           return Batting_Average_Type;
           
end Batting_Averages;
----------------------------------------------------------
package body Batting_Averages is
  ---------------------------------------------  
  function Batting_Average(BR : Batting_Record)
           return Batting_Average_Type is
    Hits  : Natural;
    BA_FL : Float;
  begin
    Hits  := BR.Singles + BR.Doubles
           + BR.Triples  + BR.Home_Runs;
    BA_FL := Float(Hits)/Float(BR.At_Bats);      -- 2 type conversions
    return Batting_Average_Type(BA_FL);          -- 1 type conversion
  end Batting_Average;
  ----------------------------------------------           
  function Slugging_Average(BR : Batting_Record)
           return Batting_Average_Type is
    Total_Bases : Natural;
    SL_FL       : Float;
  begin
    Total_Bases := BR.Singles + 2*BR.Doubles
               + 3*BR.Triples + 4*BR.Home_Runs;
    SL_FL := Float(Total_Bases)/Float(BR.At_Bats);-- 2 type conversions
    return Batting_Average_Type(SL_FL);           -- 1 type conversion
  end Slugging_Average;
  ------------------------------------------------
end Batting_Averages;
----------------------------------------------------------
----------------------------------------------------------
--------------------  Batting_Records --------------------
--  This package exports a procedure to display a set of 
--  batting and slugging averages. In its body it creates 
--  an array of batting records and an instance of the 
--  generic package Fixed_IO, exported by Ada.Text_IO. 
----------------------------------------------------------
package Batting_Records is
  procedure Display_Averages;
end Batting_Records;
----------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Batting_Averages;                    -- array of records
use type Batting_Averages.Batting_Record  -- use type clause
package body Batting_Records is
  
  BA : array (1..5) of Batting_Record
     := (("Albert Belle  ",1998,609,101,48,2,49),
         ("Ken Griffey   ",1998,633, 88,33,3,56),
         ("Mark McGuire  ",1998,509, 61,21,0,70),
         ("Sammy Sosa    ",1998,643,112,21,0,66),
         ("Greg Vaughn   ",1998,573, 78,28,4,50));
         
  package FXIO is new Fixed_IO(Batting_Average_Type);
  ------------------------------------------------------- 
  procedure Display_Averages is
  begin
    Put_Line("   Name        Year  Batting  Slugging");
    Put_Line("                     Average  Average");
    New_Line;

    for I in 1..5 loop
      Put(String(BA(I).Name) &  Natural'Image(BA(I).Year));
      Put("  ");
      FXIO.Put(Batting_Average(BA(I))); 
      Put("   "); 
      FXIO.Put(Slugging_Average(BA(I)));
      New_Line;  
    end loop;
  
  end Display_Averages;
  ------------------------------------------------
end Batting_Records;
----------------------------------------------------------
----------------------------------------------------------
---------------------- Test_Records ---------------------
--  This test procedure simply makes a procedure call 
--  to Display_Averages.
----------------------------------------------------------
with Batting_Records;
procedure Test_Records is
begin
  Batting_Records.Display_Averages;
end Test_Records;
--------------------------------------------------

The above program produces the following output:

        Name       Year  Batting  Slugging
                         Average  Average

     Albert Belle  1998   0.328    0.655
     Ken Griffey   1998   0.284    0.627
     Mark McGuire  1998   0.299    0.752
     Sammy Sosa    1998   0.309    0.650
     Greg Vaughn   1998   0.279    0.604

Related Topics

4.1 Type System Overview

[ Back to top of pagePrev ] Next ]