passing an array to a function and returning array

General FreeBASIC programming questions.
rbokslag
Posts: 2
Joined: Nov 14, 2011 17:22

passing an array to a function and returning array

Postby rbokslag » Nov 14, 2011 17:26

I have an array with 5 data points that need to be evaluated in a function. Then i want the results returned from the function in an other 5 value array.

can't figure out how to get this to work...

Thanks
Richard
Posts: 3030
Joined: Jan 15, 2007 20:44
Location: Australia

Postby Richard » Nov 14, 2011 17:42

Code: Select all

Const As Integer n = 5  ' constants are global
Dim As Double a(1 To n), b(1 To n)

Sub modify( c() As Double, d() As Double)
    For i As Integer = 1 To n
        d(i) = c(n - i + 1)
    Next i
End Sub

' initial values
For i As Integer = 1 To n
    a(i) = 10 * i
Next i

modify( a(), b() )

' results
For i As Integer = 1 To n
    Print i, a(i), b(i)
Next i

Sleep
Roland007
Posts: 80
Joined: Oct 26, 2009 21:01

Re: passing an array to a function and returning array

Postby Roland007 » Nov 14, 2011 18:46

rbokslag wrote:I have an array with 5 data points that need to be evaluated in a function. Then i want the results returned from the function in an other 5 value array.

can't figure out how to get this to work...

Thanks


You can as the example shows, use a second array. You can also, re-use the existing area by replacing element x, with the result of the evaluation of x. Arrays are passed by Reference, so changing element X of an array, from 1 to 12 inside a routine, will remain 12 after the change.

Succes
rbokslag
Posts: 2
Joined: Nov 14, 2011 17:22

Postby rbokslag » Nov 14, 2011 19:19

Thanks for the quick replies. This makes sense. I never thought of using a SUB for this.

THANKS
dodicat
Posts: 6687
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: passing an array to a function and returning array

Postby dodicat » Nov 14, 2011 19:27

Roland007 wrote:
rbokslag wrote:I have an array with 5 data points that need to be evaluated in a function. Then i want the results returned from the function in an other 5 value array.

can't figure out how to get this to work...

Thanks


You can as the example shows, use a second array. You can also, re-use the existing area by replacing element x, with the result of the evaluation of x. Arrays are passed by Reference, so changing element X of an array, from 1 to 12 inside a routine, will remain 12 after the change.

Succes


Well -- you can't in this example, because you alter values as you go along.
You need to make an internal copy of the array, then alter the array by accessing elements via the copy.

Code: Select all

Const As Integer n = 5  ' constants are global
Dim As Double a(1 To n)', b(1 To n)

Sub modify( c() As Double)
    redim as double copy(lbound(c) to ubound(c))
    for i as integer= lbound(copy) to ubound(copy)
     copy(i)=c(i)
     next i
    For i As Integer = 1 To n
        c(i) = copy(n - i + 1)
    Next i
End Sub

' initial values
For i As Integer = 1 To n
    a(i) = 10 * i
Next i

modify( a() )

' results
For i As Integer = 1 To n
    Print i, a(i)', b(i)
Next i

Sleep
 
Richard
Posts: 3030
Joined: Jan 15, 2007 20:44
Location: Australia

Postby Richard » Nov 14, 2011 23:10

One question here is; why might one need to return the entire array on the stack from an inline function. There is also a problem of finding syntax that permits you to return the entire resulting array from an inline function without tangling the function syntax. A function is just a Sub that returns something on the stack.
I see a couple of alternate ways; firstly by using pointers to the arrays, and secondly by embedding the array into a UDT, which would be my preferred solution. But, luckily, the problem is solved with the Sub.
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Nov 15, 2011 5:56

For x86, procedures that return a value normally place the value in a register or registers. For 32-bit compilers under Windows (and until some time fairly recently under Linux, BSD, and Mac OS), the norm is to return 32-bit values in EAX, 64-bit values in EDX:EAX, and floating-point values in ST(0). See Register Usage in Agner Fog’s calling_conventions.pdf, available here:

http://www.agner.org/optimize/#manuals
fxm
Posts: 9947
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Nov 16, 2011 21:21

Richard wrote:There is also a problem of finding syntax that permits you to return the entire resulting array from an inline function without tangling the function syntax. A function is just a Sub that returns something on the stack.
I see a couple of alternate ways; firstly by using pointers to the arrays, and secondly by embedding the array into a UDT, which would be my preferred solution.

- If we use a 'function () As UDT', the object containing the array is entirely passed in the stack, and consequently the available array size is limited by the free stack size.

Code: Select all

Type UDT
'  array(2047, 2047) As Byte ' does not work (stack overflow => crash)
  array(511, 511) As Byte
End Type

Function Get_Array () As UDT
  Static UDT0 AS UDT ' not in stack
  For I As Integer = 0 To 9
    For J As Integer = 0 To 9
      UDT0.array(I, J) = I * 10 + J
    Next J
  Next I
  Function = UDT0 ' a copy of UDT0 is put in the stack,
  Erase UDT0.array ' then we can erase array of UDT0
End Function

Dim Shared UDT1 As UDT ' not in stack
UDT1 = Get_Array()
For I As Integer = 0 To 9
  For J As Integer = 0 To 9
    Print Using "###"; UDT1.array(I, J);
  Next J
  Print "..."
Next I
Print "..."
Print "array size:"; Sizeof(UDT); " bytes ="; Sizeof(UDT) / 1024 / 1024; " MB"
Sleep
'array(511, 511) As Byte' works, but not 'array(2047, 2047) As Byte' (stack overflow => crash).


- If we use a 'function () As UDT Ptr', only the pointer to the object containing the array is passed in the stack, and consequently the available array size is not limited by the free stack size.

Code: Select all

Type UDT
    array(2047, 2047) As Byte
End Type

Function Get_Array () As UDT Ptr
  Static UDT0 AS UDT ' not in stack
  For I As Integer = 0 To 9
    For J As Integer = 0 To 9
      UDT0.array(I, J) = I * 10 + J
    Next J
  Next I
  Function = @UDT0 ' a pointeur to UDT0 is put in the stack,
'  Erase UDT0.array ' then we cannot erase array of UDT0
End Function

Dim UDT1pt As UDT Ptr = Get_Array()
For I As Integer = 0 To 9
  For J As Integer = 0 To 9
    Print Using "###"; UDT1pt->array(I, J);
  Next J
  Print "..."
Next I
Print "..."
Print "array size:"; Sizeof(UDT); " bytes ="; Sizeof(UDT) / 1024 / 1024; " MB"
Sleep
'array(2047, 2047) As Byte' works.
Last edited by fxm on Sep 29, 2012 12:17, edited 1 time in total.
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Postby podvornyak » Nov 29, 2011 14:58

Code: Select all

dim as integer a(0 to 4)

print "-= pointers to array =-"

sub evalute(a as integer ptr, n as integer)
   for i as integer = 0 to n
      a[i]=i*2
   next i
end sub

print
print "before evalute ";
for i as integer = 0 to ubound(a)
   print a(i);
next i


' @a(0) - memory adress of array
' ubound(a) - number of last array element

evalute(@a(0), ubound(a))

print
print "after evalute  ";
for i as integer = 0 to ubound(a)
   print a(i);
next i

evalute(@a(3), 1)

print
print "particular evalute  ";
for i as integer = 0 to ubound(a)
   print a(i);
next i

' byref - reference to original data position (like pointer)
' byval - makes copy of original data

print
print
print "-= use of reference and value options =-"

dim as integer b=1

print
print "b =";b

sub nochange(byval b1 as integer) 'byval
   b1=5
end sub

nochange(b)

print
print "after nochange(b) b =";b

sub change(byref b1 as integer) 'byref
   b1=5
end sub

change(b)

print
print "after change(b) b =";b

Return to “General”

Who is online

Users browsing this forum: No registered users and 5 guests