Page 1 of 1

Can a procedure return multiple values?[CLOSE]

Posted: Fri Mar 02, 2007 11:17 am
by SkyManager
Please correct me if I am wrong.
PB procedure can not return array or structure
For example, I need a procedure to return to me a point or a location which are having at least two variables (position X and position Y). Sometimes, I need more such as Color, or 3-dimension vector value.

My question is :
Is there any alternative for a procedure to return multiple values :?:

Posted: Fri Mar 02, 2007 11:33 am
by srod
Your best bet is to pass a pointer to a structure as one of your procedure parameters and then have the procedure modify the fields of the structure.

Code: Select all

Structure test
  a.l
  b.l
EndStructure

Procedure ModifyStruc(*ts.test)
  *ts\a=100
EndProcedure

;Dummy data.
x.test
  x\a = 1
Debug x\a

;Pass to the procedure.
ModifyStruc(@x)  ;@ is the 'address of...' operator.
Debug x\a  ;See, the value has changed.
Alternative methods include having the procedure returning a pointer to a newly allocated block of memory etc. However, the calling program then has to take steps to free the memory etc.

Posted: Fri Mar 02, 2007 11:45 am
by Kale
Heres a simple way that multiple values can be returned by a procedure:

Code: Select all

Procedure.l MakePoints(Value.l)
    Static Coords.POINT
    Coords\x = Value & $FFFF
    Coords\y = (Value >> 16) & $FFFF
    ProcedureReturn @Coords
EndProcedure

*Screen.POINT = MakePoints(67109632)

Debug *Screen\x
Debug *Screen\y
Here you are returning a single 32bit long which is an address in memory to the data you need. You then use a structured pointer to access that data.

Read this:
http://www.purebasic.fr/english/viewtopic.php?t=10753

Posted: Fri Mar 02, 2007 12:26 pm
by akj
Here's another way of returning multiple values:

Code: Select all

; Return Multiple Results from Procedure  AKJ  02-Mar-07

Procedure.d CircleInfo(radius.d, *area, *circum)
; Return the area and circumference for a circle of given radius
Protected area.d, circ.d
area = #PI*radius*radius: PokeD(*area, area)
circ = 2*#PI*radius: PokeD(*circum, circ)
EndProcedure

; Main program
Define a.d, c.d ; Area and circumference
CircleInfo(5.0, @a, @c)
Debug "Area = "+StrD(a)+"   Circumference = "+StrD(c)
End

Posted: Fri Mar 02, 2007 12:50 pm
by SkyManager
Hi, Kale,

In your sample code, you use a structure POINT. Do I need to create the POINT structure using the Declare statement before the MakePoints method?

Code: Select all

Procedure.l MakePoints(Value.l)
    Static Coords.POINT
    Coords\x = Value & $FFFF
    Coords\y = (Value >> 16) & $FFFF
    ProcedureReturn @Coords
EndProcedure

*Screen.POINT = MakePoints(67109632)

Debug *Screen\x
Debug *Screen\y 

Posted: Fri Mar 02, 2007 1:16 pm
by GedB
SkyManager,

POINT is a built in structure.

You can see its definition in the Structure Viewer, available from the Tools menu of the IDE.

btw. Welcome to PureBasic. Keep the questions coming.