Using a function as a parameter in another function.
One of the amazing features of the Pascal programming language is the possibility to create custom types, and these types being allowed to be a little bit whatever the programmer wants. In this short tutorial, I show how we can define a custom type, that is not a new data type (based on some existing data type), but a "function type", i.e. a type that may be used to declare functions as variables of this type. This is a really easy way to pass a function as parameter to another function, or a procedure.
As example, lets take a function (I called it "Trigo"), that calculates the sine, cosine, tangent, or cotangent of an angle. The function should have two arguments: the trigonometric function, and the angle in degrees.
First, lets declare a new "function type":
type
TTrigoFunction = function(const Angle: Real): Real;
Then, lets declare our 4 trigonometric functions.
function Sine(const X: Real): Real;
begin
Result := Sin(X);
end;
function Cosine(X: Real): Real;
begin
Result := Cos(X);
end;
function Tangent(X: Real): Real;
begin
Result := Sin(X) / Cos(X);
end;
function Cotangent(X: Real): Real;
begin
Result := Cos(X) / Sin(X);
end;
Now, our "Trigo" function (the function DegToRad having been declared before...):
function Trigo(TrigoFunction: TTrigoFunction; Angle: Real): Real;
begin
Result := TrigoFunction(DegToRad(Angle));
end;
Finally the main program, that asks the user for a function and an angle, and displays the function value. Note that the functions Power()
and RFormat() are used to get a formatted output of real numbers.
program functions;
uses
SysUtils;
type
TTrigoFunction = function(const Angle: Real): Real;
var
rAngle: Real;
sFunction: string;
bContinue: Boolean;
// Declarations of the functions Power() and RFormat() to be inserted here ...
function DegToRad(Angle: Real): Real;
begin
Result := 2 * Pi * Angle / 360;
end;
// Declarations of the 4 trigonometric functions Sine, Cosine, Tangent, and Cotangent (cf. above) to insert here...
function Trigo(TrigoFunction: TTrigoFunction; Angle: Real): Real;
begin
Result := TrigoFunction(DegToRad(Angle));
end;
{* Main program *}
begin
Writeln('Trigonometric functions:');
repeat
bContinue := True;
Write('Function (sin, cos, tan, cotan)? '); Readln(sFunction);
if (sFunction = 'sin') or (sFunction = 'cos') or (sFunction = 'tan') or (sFunction = 'cotan') then begin
Write('Angle (in degrees) ? '); Readln(rAngle);
if sFunction = 'sin' then
Writeln('sin(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Sine, rAngle),
3))
else if sFunction = 'cos' then
Writeln('cos(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Cosine, rAngle),
3))
else if sFunction = 'tan' then
Writeln('tan(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Tangent, rAngle),
3))
else
Writeln('cotan(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Cotangent, rAngle),
3));
end
else
bContinue := False;
Writeln;
until not bContinue;
end.
I think that it's quite obvious that functions have to be passed to a function using pointers. Thus, we'll have to prefix the function name with the address operator @.
The screenshot shows a sample execution of the program.
If you find this text helpful, please, support me and this website by signing my guestbook.