Returning Multiple Values (Advanced)

Top  Previous  Next

An "address" operator can be used to return more than one value from a function. Values can always be returned by passing them through global variables, but a better way in some cases is to return them using pointers. For example:

 

        code    ChOut=8, CrLf=9, IntOut=11;

        int     Frog, Pig(11);

        int     Low1, High1, Low2, High2, I;

 

                proc    MinMax(Array, Size, Min, Max);

                \Returns the minimum and maximum values of the array

                int     Array, Size, Min, Max;

                int     I;

                begin

                Min(0):= Array(0);   Max(0):= Array(0);

                for I:= 1, Size-1 do

                        begin

                        if Array(I) < Min(0) then Min(0):= Array(I);

                        if Array(I) > Max(0) then Max(0):= Array(I);

                        end;

                end;    \MinMax

 

        begin   \Main

        Frog:= [16, 23, 127, -33, 0];

        MinMax(Frog, 5, addr High1, addr Low1);

        for I:= 0, 10 do Pig(I):= 2*I*I - 16*I + 20;

        MinMax(Pig, 11, addr High2, addr Low2);

        IntOut(0, High1);   ChOut(0, $09);   IntOut(0, Low1);   CrLf(0);

        IntOut(0, High2);   ChOut(0, $09);   IntOut(0, Low2);   CrLf(0);

        end;    \Main

 

This program displays the following:

 

        -33     127

        -12     60

 

The program displays the minimum and maximum values for two arrays. The calls to MinMax pass the addresses of the High and Low variables, which get values returned to them. The MinMax procedure uses a zero subscript with Min and Max to access the original variables in the calling routine. Compare this to the normal way arguments are passed, where only the value in a variable is passed to a procedure and the procedure does not have access to the variable.

 

Here is another example of using the address operator to pass values to and from a procedure, this time using reals. This is tricky since the address of a real variable is a 2-byte integer. Three dummy integers (the 0's) are passed along with the address to fill out an 8-byte real (AX). Actually these 0's are not needed here; they are only needed when another argument follows the address argument.

 

code CrLf=9;

code real RlOut=48, Sqrt=53, ATan2=57;

 

proc Rect2Polar(X,Y,A,D); \Return polar coordinates

real X,Y,A,D;

begin

A(0):= ATan2(Y,X);

D(0):= Sqrt(X*X+Y*Y);

end; \Rect2Polar

 

real Ang, Dist;

begin

Rect2Polar(4.0, 3.0, @Ang, @Dist);

RlOut(0, Ang);

RlOut(0, Dist);

CrLf(0);

end;

 

Note the use of "@" instead of "addr". The "addr" operator doesn't quite  work in this situation because it returns an integer address, and what we  need here are pointers to the real variables Ang and Dist. A real pointer  is a 32-bit address, but it's packaged in a 64-bit value so it can be  handled like a real. It's actually just a 32-bit integer with three more  zero integers tacked on. The "@" works exactly the same way as "addr" on  integer variables, but it returns a real pointer when used on real variables.

 

When the above program runs, it displays (angle in radians):

 

0.64350        5.00000