Seite 1 von 1

Wie kann eine Procedure mehr als ein Ergebnis zurückliefern

Verfasst: 30.04.2012 17:08
von Lothar Schirm
:( Ich setze gerade ein paar meiner Werke von FreeBASIC auf PureBasic um. Dort sowie in anderen BASIC-Dialekten gibt es die Möglichkeit, mehrere Parameter an eine Prozedur (SUB) "by reference" (BYREF) zu übergeben, so dass diese z.B. innerhalb der Prozedur verändert bzw. berechnet und dann ausgegeben werden können. Beispiel: Rotation eines Punktes (x, y, z) um die z-Achse, Drehwinkel gamma. In FreeBASIC kann man dazu eine Prozedur wie folgt schreiben:

SUB (x AS DOUBLE, y AS DOUBLE, gamma AS DOUBLE, BYREF xrot AS DOUBLE, BYREF yrot AS DOUBLE)
' x, y = Koordinaten vor der Rotation
'xrot, yrot = Koordinaten nach der Rotation (z ändert sich nicht)
(Code ....)
END SUB

Wie macht man das in PureBASIC? Geht das nur, wenn man die zu berechnenden Parameter in eine Structure oder in ein Array packt? Ist halt ein bisschen umständlich.

Re: Wie kann eine Procedure mehr als ein Ergebnis zurücklie

Verfasst: 30.04.2012 17:45
von ts-soft
Erstmal als Einstieg:

Code: Alles auswählen

EnableExplicit

Procedure foo(*text.string, *a.long, *b.Integer)
  *text\s = "Hallo"
  *a\l = 500
  *b\i = 500
EndProcedure

Define Text.String
Define a.l, b.i

foo(@Text, @a, @b)

Debug Text\s
Debug a
Debug b
Einzige Besonderheit sind der String.
Jetzt kannste auch gezielter Nachfragen, wenn Du etwas nicht versteht.

Gruß
Thomas

Re: Wie kann eine Procedure mehr als ein Ergebnis zurücklie

Verfasst: 30.04.2012 18:14
von Lothar Schirm
Vielen Dank, Thomas. Funktioniert auch gut, wenn ich im Prozedurkopf *b.double hinschreibe und in der Prozedur für b z.B. eine Division (z.B. 2/3) hinschreibe, die wird richtig mit allen Dezimalstellen ausgeführt.

Warum muss man in diesem Fall die Variablentypen im Prozedurkopf ausschreiben (.string, .long, .double), warum reicht nicht .s, .l. .d? Und in wieweit sind Strings eine Besonderheit? So richtig scheint mir das alles in der PureBasic-Hilfe nicht dokumentiert zu sein.

Re: Wie kann eine Procedure mehr als ein Ergebnis zurücklie

Verfasst: 30.04.2012 18:22
von ts-soft
Normaler weise würde man die Werte hineinpoken. Um dieses zu vereinfachen, gibt es jeden Variablentyp auch als
Strukture, so das man leichter direkt in die Adresse schreiben kann.

Auf http://www.purearea.net unter Tutorials findest Du auch noch ein PointerTut, welches Du Dir auch mal ansehen solltest.
http://www.purearea.net/pb/download/tut ... TER_v4.zip

Strings können ja niemals direkt übergeben werden, sondern erwecken nur den Anschein byVal :mrgreen:
Strings werden als immer ByRef übergeben, jedenfalls intern. Beim Poken in den String, würdest Du also in die
Adresse, die die Adresse des Strings beinhaltet, reinpoken, was natürlich schief gehen muss.

So wie im obigen Beispiel sollte es sicher sein und auch vom Stringmanager verarbeitet werden, der ja den Speicher
für den String reservieren muss.

Listen, Arrays usw. werden grundsätzlich ByRef übergeben, also Änderungen wirken sich also nicht nur Lokal aus.

Gruß
Thomas

//edit
Nachtrag: Die vordefinierten Structuren für die einfachen Variablen, sehen alle nach diesem Schema aus:

Code: Alles auswählen

Structure Long
  l.l
EndStructure

Re: Wie kann eine Procedure mehr als ein Ergebnis zurücklie

Verfasst: 30.04.2012 19:51
von Lothar Schirm
Vielen Dank,
jetzt habe ich es glaube ich verstanden.