A record can be passed as a parameter to a function or procedure, provided that the actual parameter is of the same type as its corresponding formal parameter. The use of records as parameters can shorten parameter lists considerably because one parameter (the record variable) can be passed instead of several related parameters.
Ada normally uses procedures to read data from the terminal or a file. The
Get
procedures available in the input/output packages are defined
only for individual values, not for records. To read a record, we can use a
call of the appropriate Get
to read each field. It is common to
read an entire record at once, so it makes sense to define a procedure for
doing this; the body of the procedure will contain the individual
Get
calls for each record field.
Example 8.4
Program
8.2 contains a procedure GetPoint
to read a point in the
x-y plane and a function Distance
, which calculates the
distance between two points P1 = (X1 ,Y1) and P2 =
(X2 , Y2) . The formula used to calculate the distance d
is
_________________________ d = \/( X2 - X1)2 + ( Y2 - Y1)2The main program requests the coordinates of two points from the user, then calculates and displays the distance between them. Notice how straightforward it is to write and call subprograms with record parameters.
Program 8.2
WITH Ada.Text_IO; WITH Ada.Float_Text_IO; WITH Ada.Numerics.Elementary_Functions; USE Ada.Numerics.Elementary_Functions; PROCEDURE Distance_between_Points IS ------------------------------------------------------------------------ --| Finds the distance between two points on the x-y plane. --| Author: Michael B. Feldman, The George Washington University --| Last Modified: July 1995 ------------------------------------------------------------------------ TYPE Point IS RECORD X : Float; Y : Float; END RECORD; Point1 : Point; -- one data point Point2 : Point; -- the other data point PROCEDURE GetPoint(Item: OUT Point) IS -- Pre: none -- Post: the point, Item, is defined with values from the user BEGIN Ada.Text_IO.Put(Item => "Enter X coordinate (floating point) > "); Ada.Float_Text_IO.Get(Item => Item.X); Ada.Text_IO.Put(Item => "Enter Y coordinate (floating point) > "); Ada.Float_Text_IO.Get(Item => Item.Y); END GetPoint; FUNCTION Distance(P1 : Point; P2 : Point) RETURN Float IS -- Pre: P1 and P2 are defined -- Post: returns the Cartesian distance between the points BEGIN RETURN Sqrt((P2.X-P1.X) ** 2 + (P2.Y-P1.Y) ** 2); END Distance; BEGIN -- Distance_between_Points Ada.Text_IO.Put(Item => "First Point"); Ada.Text_IO.New_Line; GetPoint(Item => Point1); Ada.Text_IO.Put(Item => "Second Point"); Ada.Text_IO.New_Line; GetPoint(Item => Point2); Ada.Text_IO.Put(Item => "Distance between points is "); Ada.Float_Text_IO.Put (Item => Distance(Point1, Point2), Fore=>1,Aft=>2,Exp=>0); Ada.Text_IO.New_Line; END Distance_between_Points;Sample Run
First Point Enter X coordinate (floating point) > 3 Enter Y coordinate (floating point) > 4 Second Point Enter X coordinate (floating point) > 9 Enter Y coordinate (floating point) > 12 Distance between points is 10.00
When an entire record must be assigned at one time, it is unnecessary to assign each field in a separate assignment statement. Instead, you can use an aggregate. An aggregate is just a list of all the field values in the record, separated by commas and enclosed in parentheses. An aggregate looks like a parameter list in a procedure call: The values can just be listed in sequence (positional association) or given with their names (named association). Generally we will use the latter form because it is clearer and easier to understand.
A record Clerk
of type Employee
, as used above, could
be filled in with an aggregate assignment as follows:
Clerk := (ID => 1234, Name => "Caryn Jackson ", Gender => Female, NumDepend => 2, Rate => 7.50);We have listed the fields in the order in which they were declared in the type definition, but in fact we could have put them in any order because the field names help the compiler (and the human reader) make the association.
It is permissible to write an aggregate assignment without specifying the field names, for example,
Clerk := (1234,"Caryn Jackson ", Female, 2, 7.50);However, this form, called positional association, is not nearly as clear and also requires that the fields be listed exactly in the order in which they appear in the type definition. We will generally use the first, or named association, form of record aggregate assignment.
Exam1
and Exam2
.
PrintStat (Exam1); Exam2 := Exam1; Exam2.High := Exam2.High - 5.0; PrintStat (Exam2);
CatalogueEntry
. See Self-Check Exercise 2 at the end of Section
8.1.
Copyright © 1996 by Addison-Wesley Publishing Company, Inc.