Return an array from a Function.

New to FreeBASIC? Post your questions here.
TheAlmightyGuru
Posts: 20
Joined: Feb 18, 2008 21:35
Location: Grand Blanc, MI 48439
Contact:

Return an array from a Function.

Postby TheAlmightyGuru » Jul 25, 2014 21:12

Does FreeBASIC support Functions returning arrays? The help shows how to pass in an array, but I couldn't find anything about returning an array. I've tried various forms for declaring the function including using passing in an array ByRef, but the compiler doesn't seem like anything I do.

Without getting into too much detail about my program, I need something along the lines of passing in a string like "test" and get back a Byte array of the ASCII values of each character (116, 101, 115, 116)?

Thanks!
dodicat
Posts: 6718
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Return an array from a Function.

Postby dodicat » Jul 25, 2014 22:11

Passing an array, byref or byval are not used.
The array is passed byref by default.

So, you can build the array in a sub .

An array pointer could be returned from a function, but not an array.

Code: Select all


sub test(t as string,a() as ubyte)
     redim a(len(t)-1)
    for n as integer=0 to len(t)-1
    a(n)=t[n]
    next n
end sub

dim as ubyte a()
dim as string s="123456789"+"   "+"Test"
test(s,a())
for n as integer=0 to len(s)-1
    print a(n)
next n

print
for n as integer=0 to len(s)-1
    print chr(a(n));
next n
sleep
maves_moya
Posts: 32
Joined: May 27, 2006 13:54
Location: Maldives

Re: Return an array from a Function.

Postby maves_moya » Jul 25, 2014 22:17

Try this:

Code: Select all

DECLARE SUB printSeries(S() AS INTEGER)
DECLARE FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR


dim as integer series(10)
fibonacci(series())
printSeries series()

'======================================================

FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR
   s(LBOUND(S))=1 : s(LBOUND(S)+1)=1
   FOR n AS INTEGER = LBOUND(S)+2 TO UBOUND(S)
      s(n) = (s(n-2))+(s(n-1))
   NEXT n
   return @S(0)      '<--------
END FUNCTION


SUB printSeries(S() AS INTEGER)
   FOR N AS INTEGER = LBOUND(S) TO UBOUND(S)
      print s(N)
   NEXT N
END SUB


Hope this helps.
Regards.
MrSwiss
Posts: 3631
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Return an array from a Function.

Postby MrSwiss » Jul 25, 2014 22:35

I need something along the lines of passing in a string like "test" and get back a Byte array of the ASCII values of each character (116, 101, 115, 116)?

Well as a short idea I whould do something like:

Code: Select all

Dim As ZString*128 s
Dim As Any Ptr sp = @s
Dim As UByte(0 to 127) res
Dim As UByte Ptr resp = @res

Sub String-Byte_to_ASCCI-UByte (source As Any Ptr, result As UByte Ptr)
...
'' using source and result
...
End Sub


'' fill Stringbuffer with something like
s = "Test"
'' calling the sub from CODE
String-Byte_to_ASCCI-UByte(sp, resp)

With the above construct your Sub can READ the String (Byte by Byte) and at the same time
MODIFY the UByte Array, which then contains the result. There is no need for a Function here.
dodicat
Posts: 6718
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Return an array from a Function.

Postby dodicat » Jul 25, 2014 23:02

maves_moya wrote:Try this:

Code: Select all

DECLARE SUB printSeries(S() AS INTEGER)
DECLARE FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR


dim as integer series(10)
fibonacci(series())
printSeries series()

'======================================================

FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR
   s(LBOUND(S))=1 : s(LBOUND(S)+1)=1
   FOR n AS INTEGER = LBOUND(S)+2 TO UBOUND(S)
      s(n) = (s(n-2))+(s(n-1))
   NEXT n
   return @S(0)      '<--------
END FUNCTION


SUB printSeries(S() AS INTEGER)
   FOR N AS INTEGER = LBOUND(S) TO UBOUND(S)
      print s(N)
   NEXT N
END SUB


Hope this helps.
Regards.


Yes, but return @s(0) could be return 0, it makes no difference.
You are still filling the array you passed in the function.
dodicat
Posts: 6718
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Return an array from a Function.

Postby dodicat » Jul 25, 2014 23:36

You could also do:

Code: Select all


sub PassBack(byref u as ubyte ptr,byref t as string)
    for n as integer=0 to len(t)-1:u[n]=t[n]:next
end sub


dim as string t="Test this out."
dim as ubyte b(len(t)-1)

PassBack(@b(0),t)

print
for n as integer=0 to ubound(b)
    print b(n),chr(b(n))
    next n
sleep

 
TheAlmightyGuru
Posts: 20
Joined: Feb 18, 2008 21:35
Location: Grand Blanc, MI 48439
Contact:

Re: Return an array from a Function.

Postby TheAlmightyGuru » Jul 26, 2014 1:42

Thank you all so much for the responses, and I was able to get my program working using a sub routine like several of your examples show.

You guys are awesome!
maves_moya
Posts: 32
Joined: May 27, 2006 13:54
Location: Maldives

Re: Return an array from a Function.

Postby maves_moya » Jul 26, 2014 4:42

You are right.
dodicat wrote:
maves_moya wrote:Try this:

Code: Select all

DECLARE SUB printSeries(S() AS INTEGER)
DECLARE FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR


dim as integer series(10)
fibonacci(series())
printSeries series()

'======================================================

FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR
   s(LBOUND(S))=1 : s(LBOUND(S)+1)=1
   FOR n AS INTEGER = LBOUND(S)+2 TO UBOUND(S)
      s(n) = (s(n-2))+(s(n-1))
   NEXT n
   return @S(0)      '<--------
END FUNCTION


SUB printSeries(S() AS INTEGER)
   FOR N AS INTEGER = LBOUND(S) TO UBOUND(S)
      print s(N)
   NEXT N
END SUB


Hope this helps.
Regards.


Yes, but return @s(0) could be return 0, it makes no difference.
You are still filling the array you passed in the function.


Thanks, dodicat for pointing that out.
Like you said it is pointless in this case, since arrays are passed by reference to the function

I was trying to demonstrate how to use pointers to array, like you've mentioned above.
More like this, I guess:

Code: Select all

DECLARE SUB printSeries(S AS INTEGER PTR)
DECLARE FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR
#define NULLPTR 0

dim as integer series(5)
printSeries fibonacci(series())

'======================================================
FUNCTION fibonacci(S() AS INTEGER) AS INTEGER PTR
   if lbound(s) <> 0 THEN RETURN NULLPTR
    s(LBOUND(S))=1 : s(LBOUND(S)+1)=1
    FOR n AS INTEGER = LBOUND(S)+2 TO UBOUND(S)
        s(n) = (s(n-2))+(s(n-1))
    NEXT n
    return @S(0)        '<--------
END FUNCTION

SUB printSeries(S AS INTEGER PTR)
   IF S = NULLPTR THEN END
   DIM AS INTEGER bound = *(s-1)             '<--- I'm not sure about FB's ARRAY struct for INT, but I guess this will work..
    FOR N AS INTEGER = 0 TO bound
            print s[n]
    NEXT N
END SUB
 


I hope this works.
Regards.
fxm
Posts: 9980
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Return an array from a Function.

Postby fxm » Jul 26, 2014 5:56

Why do you want to return a Byte array of the ASCII values of each character of a string?
Already it exists the operator '[]' (String Index) allowing to return a reference (Ubyte) to a character in a string (String or Zstring):

Code: Select all

Dim As String s ="Hello, world!"

For I As Integer = 0 To Len(s) - 1
    Print s[I], Chr(s[I])
Next I
Sleep
fxm
Posts: 9980
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Return an array from a Function.

Postby fxm » Jul 28, 2014 6:09

Returning to the title of this topic which is more general: 'Return an array from a Function'

If we want that the function returns by value an array with its structure (its descriptor) without passing this array by reference (neither by defining it as shared), one solution is that the function returns by value an object containing the array.

Now with the development version of FB (fbc 0.91.0), an UDT accepts dynamic arrays as members, that which induces more flexibility to return packaged arrays.

Example to return an ordered array (by increasing values) of the ASCII values of a string (to be compile with FBC 0.91.0):

Code: Select all

Type UDTarray
  Dim As Ubyte array(Any)
End Type

Function returnUDTarrayOrdered (Byref s0 As String) As UDTarray
  Dim As UDTarray u0
  If Len(s0) > 0 Then
    Redim u0.array(Len(s0) - 1)
    For I As Integer = 0 To Len(s0) -1
      u0.array(I) = s0[I]
      Dim As Integer K = I
      While K > 0 Andalso u0.array(K) < u0.array(K - 1)
        Swap u0.array(K), u0.array(K - 1)
        K -= 1
      Wend
    Next I
  End If
  Function = u0
End Function

Dim As String s = "Hello, world!"
Dim As UDTarray u = returnUDTarrayOrdered(s)
For I As Integer = 0 To Ubound(u.array)
  Print u.array(I), Chr(u.array(I))
Next I

Sleep

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 3 guests