In Section 3.6, you saw how to use some predefined functions in a package, the
Month
, Day
, and Year
functions in the
standard package
Ada.Calendar;
in the previous section you saw how to use the square root function from
another standard package,
Ada.Numerics.Elementary_Functions.
This section introduces the very important subject of how to write such
functions; the next section shows how to put functions in packages for yourself
and others to use again later.
Function Specifications
In general, a function is written so as to require the caller to supply some values to it. When called, the function performs its desired computation and then returns a result to the calling program. The line indicating the name of the function, the list of expected parameters, and the type of the returned result is called a function specification or sometimes function declaration. You saw three such specifications in Chapter 3:
FUNCTION Year (Date: Time) RETURN Year_Number; FUNCTION Month (Date: Time) RETURN Month_Number; FUNCTION Day (Date: Time) RETURN Day_Number;
The specification for Year
tells the compiler--and
the reader--that this function must be called with one value of type
Time
and that it returns a result of type Year_Number
to the program that calls it. The other two specifications are similar.
Here is a specification for a function to find the larger of two integer values and return it to the calling program:
FUNCTION Maximum(Value1, Value2: Integer) RETURN Integer;Notice that between the parentheses is a list of the expected parameters and that after the word
RETURN
is the type of the
returned result. In this case, the function is to determine which of the two
parameters is larger and return it as the result.
Recall from Chapter 3 that we were able to extract the year from a system-generated time value by writing
This_Year := Calendar.Year(Date => Right_Now);
where This_Year
was declared as a variable of type
Calendar.Year_Number
and Right_Now
was a variable of
type Calendar.Time
. Notice that between the parentheses is an
association of the name of the formal parameter (Date
) with
the variable containing the value of the actual parameter
(Right_Now
).
How could we use our function Maximum
in a similar way? Given
an integer variable Larger
, writing
Larger := Maximum(Value1=>24,Value2=>-57);stores the value
24
in the variable
Larger
because that is the larger of the two values. Given two
integer variables Grade1
and Grade2
, writing
Grade1 := -24; Grade2 := 113; Larger := Maximum(Value1=>Grade1,Value2=>Grade2);
stores in Larger
the value 113
, again
because that is the larger value. Notice again how the formal parameters
Value1
and Value2
are associated with the actual
parameters Grade1
and Grade2
, and notice that it is
improper to write, for example,
Larger := Maximum(Grade1=>Value1,Grade2=>Value2);
because Value1
is the formal parameter and
Grade1
is the actual. The formal parameter comes first, followed
by the actual parameter.
The difference between these two examples is that the fuction
Year
already exists (in package Calendar
) but the
function Maximum
does not. We have a specification indicating the
name of the function, how it is to be called, and what it returns, but we do
not yet actually have a function that will find the larger number.
Function Bodies
To complete our function Maximum
we need to write a
function body, that is, a small program in Ada in a form that the
compiler will recognize as a function. Here is the desired function body:
FUNCTION Maximum (Value1, Value2: Integer) RETURN Integer IS Result: Integer; BEGIN IF Value1 > Value2 THEN Result := Value1; ELSE Result := Value2; END IF; RETURN Result; END Maximum;
This function body has the basic form of an Ada program. There
is a header line similar to the first line of a program; this line ends with
the word IS
. Next there is a section of declarations; here we are
declaring only a single program variable Result
. Following the
word BEGIN
is the statement sequence of the function body, and the
function body ends with an END
. The IF
statement in
the function body stores in the variable Result
the larger of
Value1
and Value2
. Finally, the value in
Result
is returned to the calling program as the function result.
This value can be stored directly in a variable of the calling program, as in
the examples above, or used as part of an expression implementing a larger
calculation.
The variable Result
is called a local variable of the
function. Because it is declared inside the function body, it has no existence
outside the function body. It is good practice when writing a function to put
the variables needed by the function inside the function body so that
they are the private property of the function and cannot be seen or disturbed
by any other program.
To see an example of how a function is declared as part of a larger program,
consider
Program
4.6, in which the user is prompted to enter two integer values
FirstValue
and SecondValue
. These values are then
passed to the function Maximum,
which returns the larger value to
the main program. The answer is then displayed. The function
Maximum
is declared in the declaration part of the main program.
Program 4.6
Finding the Larger of Two Integer Values with a Function
WITH Ada.Text_IO; WITH Ada.Integer_Text_IO; PROCEDURE Max_Two IS ------------------------------------------------------------------------ --| Finds the larger of two integer values --| using the Maximum function --| Author: Michael B. Feldman, The George Washington University --| Last Modified: July 1995 ------------------------------------------------------------------------ FirstValue: Integer; SecondValue: Integer; Larger: Integer; -- function specification FUNCTION Maximum (Value1, Value2: Integer) RETURN Integer; -- function body FUNCTION Maximum (Value1, Value2: Integer) RETURN Integer IS Result: Integer; BEGIN IF Value1 > Value2 THEN Result := Value1; ELSE Result := Value2; END IF; RETURN Result; END Maximum; BEGIN Ada.Text_IO.Put (Item => "Please enter first integer value > "); Ada.Integer_Text_IO.Get (Item => FirstValue); Ada.Text_IO.Put (Item => "Please enter second integer value > "); Ada.Integer_Text_IO.Get (Item => SecondValue); Larger := Maximum(Value1=>FirstValue, Value2=>SecondValue); Ada.Text_IO.Put (Item => "The larger number is "); Ada.Integer_Text_IO.Put (Item => Larger, Width => 1); Ada.Text_IO.New_Line; END Max_Two;Sample Run
Please enter first integer value > 374 Please enter second integer value > -158 The larger number is 374
SYNTAX DISPLAY
Function Specification
FUNCTION fname ( formal parameters ) RETURN result type ;
FUNCTION Square (Num : Integer) RETURN Integer;
SYNTAX DISPLAY
Function Body
FUNCTION fname ( formal parameters ) RETURN result type IS local declaration section BEGIN statement sequence END fname;
FUNCTION Square (Num : Integer) RETURN Integer IS Result: Integer; BEGIN Result := Num * Num; RETURN Result; END Square;
RETURN
statement must be executed each time the
function is called.
IS
. In fact, the way the line
ends indicates to the compiler whether it should treat the line as a
specification or as the first line of a body. It is therefore important not to
confuse the two endings, lest you confuse the compiler.
Copyright © 1996 by Addison-Wesley Publishing Company, Inc.