Mehrere Rückgabewerte von Procedur

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
Maurizio555
Beiträge: 53
Registriert: 03.10.2004 10:00
Wohnort: BW

Mehrere Rückgabewerte von Procedur

Beitrag von Maurizio555 »

Wenn ich möchte, daß eine Procedur mehrere Werte zurückliefert, übergebe ich ihr (außer den/die zu verarb. Wert/e) Zeiger auf Speicherbereiche. Dadurch, daß die Procedur nicht direkt auf Variabeln sondern auf "gezeigten" Bereichen schreibt, verlieren die "Ergebnisse" nicht Ihren Gültigkeitsbereich nach Verlassen der Proc. und man vermeidet Global-Variabeln (man sollte so wenig davon benutzen wie nur möglich).
Als Beispiel (unten) habe ich den Code von Falko, um aus einem Julianischen Tag das Gregorianische Datum zu errechnen, angepasst.
Kennt jemand in PB noch eine Möglichkeit, um mehrere Ergebnisse aus einer Proc zu erhalten (natürlich ohne Globals)?

Code: Alles auswählen

;Original-Code:
Procedure DMY(JD.l) 
  Global T.b,M.w,J.w 
  N1 = JD + 32044 
  N2 = N1 / 146097 
  N3 = N1 % 146097 
  N4 = N3 / 36524 - N3 / 146096 
  N5 = N3 - 36524*N4 
  N6 = N5 / 1461 
  N7 = N5 % 1461 
  N8 = N7 / 365 - N7 / 1460 
  N9 = N7 - 365*N8 
  N10 = (111*N9 + 41) / 3395 
  T = N9-30*N10-(7*(N10 + 1)) / 12 + 1 
  M1 = N10 + 3 
  J1 = 400*N2+100*N4+4*N6+N8-4800 
  M = ((M1 + 11) % 12)+1 
  J = J1+(M1 / 13) 
EndProcedure 
DMY(LANG) 
Debug T 
Debug M 
Debug J

;Angepasster Code:
Procedure GregorTag (JulianDay.l,*d,*m,*y)
  N1 = JulianDay + 32044 
  N2 = N1 / 146097 
  N3 = N1 % 146097 
  N4 = N3 / 36524 - N3 / 146096 
  N5 = N3 - 36524*N4 
  N6 = N5 / 1461 
  N7 = N5 % 1461 
  N8 = N7 / 365 - N7 / 1460 
  N9 = N7 - 365*N8 
  N10 = (111*N9 + 41) / 3395 
  PokeW(*d,( N9-30*N10-(7*(N10 + 1)) / 12 + 1 ))
  M1 = N10 + 3 
  J1 = 400*N2+100*N4+4*N6+N8-4800 
  PokeW(*m, ((M1 + 11) % 12)+1 )
  PokeW(*y, J1+(M1 / 13) )
EndProcedure

*d=AllocateMemory(2)
*m=AllocateMemory(2)
*y=AllocateMemory(2)
GregorTag(2453006,*d,*m,*y)
Debug PeekW(*d)
Debug PeekW(*m)
Debug PeekW(*y)
Mit fernem Wasser läßt sich nicht ein nahes Feuer löschen.
Tsue Hung (525 n.Chr.).
Benutzeravatar
ralle
Beiträge: 88
Registriert: 29.11.2004 17:50
Wohnort: Berlin

Beitrag von ralle »

Nope, da zumindest meiner Kenntis nach keine benutzerdefinierten Strukturen als Rückgabewerte verwendet werden können (ist schon ein bisl länger her, dass ich das mal probiert habe. Ist das mitlerweile in PB3.92 implementiert?)
NetSlayer
Beiträge: 117
Registriert: 21.09.2004 21:18
Kontaktdaten:

Beitrag von NetSlayer »

Ich weiß nicht, ob das geht ralle, aber man kann ja den Pointer auf eine Structure zurückgeben, oder der Prozedur gleich einen Pointer auf eine Structure mitgeben, in die sie dann schreiben kann. Dürfte ja alles möglich sein.

Da Structures ja eh nur Pointer sind könnte Fred das AFAIK ziemlich schnell einbauen.
...MfG, NetSlayer
"No, I ain't got a problem. It's you with the problem!"
http://netslayer.scpn.net
sbehrens
Beiträge: 274
Registriert: 08.09.2004 18:41
Kontaktdaten:

Beitrag von sbehrens »

Konzept:
Man steckt alle Rückgabewerte in einen Wert, und filtert sie später wieder raus. Beispielsweise könnte man wenn man strings hat diese einfach mit einem Trennzeichen trennen ("|" oder Chr(0) usw.) oder falls man Zahlen hat, diese erst in Strings verwandeln, dann in einen String packen, den Rückgabewert wieder in die verschiedenen Strings aufteilen und diese Strings wieder in Zahlen umwandeln. Wäre eine Möglichkeit, oder? (Könnte etwas unsicher sein, an dem Konzept muss man noch arbeiten, ist mir nur spontan eingefallen. Aber bevor man mit einem übelst komplizierten Verfahren arbeitet...)

mfG
Basti
enjoy life... while you can!
NetSlayer
Beiträge: 117
Registriert: 21.09.2004 21:18
Kontaktdaten:

Beitrag von NetSlayer »

ptI hat geschrieben:Konzept:
Man steckt alle Rückgabewerte in einen Wert, und filtert sie später wieder raus. Beispielsweise könnte man wenn man strings hat diese einfach mit einem Trennzeichen trennen ("|" oder Chr(0) usw.) oder falls man Zahlen hat, diese erst in Strings verwandeln, dann in einen String packen, den Rückgabewert wieder in die verschiedenen Strings aufteilen und diese Strings wieder in Zahlen umwandeln. Wäre eine Möglichkeit, oder? (Könnte etwas unsicher sein, an dem Konzept muss man noch arbeiten, ist mir nur spontan eingefallen. Aber bevor man mit einem übelst komplizierten Verfahren arbeitet...)

mfG
Basti
Das ist aber nicht so die optimale Lösung, denn es ist verhältnismäßig langsam aus Zahlen Strings zu machen und aus diesen wieder Zahlen zu machen (Binär => ASCII => Binär), darum ist die Version mit dem Pointer wohl besser, da die Daten nicht verändert, bzw. vor der Verwendung bearbeitet/umgewandelt werden müssen.

PS: Du kannst nicht mehrere Strings in einem String mit einem 0-Zeichen trennen, denn die 0 suggeriert PB, dass der String dort zuende ist.
...MfG, NetSlayer
"No, I ain't got a problem. It's you with the problem!"
http://netslayer.scpn.net
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Ich bin mir nicht sicher ob ich das Problem richtig verstanden habe.
Warum nicht einfach zeiger auf eigene Struktur der Funktion übergeben, warum muss es unbedingt Ruckgabe wert.

Warum nicht einfach so:

Code: Alles auswählen

Structure mystruct
  ;hier felder von endsprechendem Typ
Endstructure

Procedure.l myprocedure(*data.mystruct)
   ;hier alles mögliche in die Struktur schreiben 
    ....
   ProcedureReturn 0;
EndProcedure
.....
Deftype.mystruct data
.....
myprocedure(@data)
.....
End


Ich doch so simpel. Die Funktion bearbeitet die Felder der Struktur und man kann so mehrere (in einem Aufruf) Ergibnise aus einer Funktion bekomen.
Kennt jemand in PB noch eine Möglichkeit, um mehrere Ergebnisse aus einer Proc zu erhalten
Das ist doch die Lösung.Warum hier Ruckgabewert benutzen.
Oder habe ich das Problemm falsch verstanden?
Zuletzt geändert von MARTIN am 15.12.2004 22:35, insgesamt 2-mal geändert.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
NetSlayer
Beiträge: 117
Registriert: 21.09.2004 21:18
Kontaktdaten:

Beitrag von NetSlayer »

NetSlayer hat geschrieben:..., oder der Prozedur gleich einen Pointer auf eine Structure mitgeben, in die sie dann schreiben kann.
Jo, war auch mein Gedanke, wie du siehst ;)
...MfG, NetSlayer
"No, I ain't got a problem. It's you with the problem!"
http://netslayer.scpn.net
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Also habe ich das doch richtig verstanden.
War etwas verwirren weil ,obwohl einen Zeiger zu übergeben wohl die eleganteste und einfachste Lösung ist, hat ptI vorgeschlagen, Ergibnise in die Ruckgabewert zu "kodieren" so als aus iregendeinem Grund nicht möglich wäre das ganze mit einen Zeiger zu lösen. Den Grund konnte ich aber nicht erkennen.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Ähm... kannst du das noch mal erklären? Ich hab nix verstanden.
Benutzeravatar
Lars
Beiträge: 347
Registriert: 31.08.2004 23:53
Wohnort: Shanghai
Kontaktdaten:

Beitrag von Lars »

Du kannst auch wirklich Werte zurück geben, wie das hier zeigt:

Code: Alles auswählen

Structure AddAndMultiplicateResult
  Sum.l
  Product.l
EndStructure

Procedure.l AddAndMultiplicate(a.l, b.l)
  result.AddAndMultiplicateResult
  
  result\Sum     = a + b
  result\Product = a * b
  
  ProcedureReturn result
EndProcedure

*result.AddAndMultiplicateResult = AddAndMultiplicate(10, 10)

Debug *result\Sum
Debug *result\Product
Was hier wichtig ist: Die Variable result ist hier die variable einer Procedur
und wird damit im Prinzip nach beenden der Procedur gelöscht. Direkt
nach Beenden kannst du noch darauf zugreifen, wenn du aber da mal ein
Delay(2000) zwischen Procedure Call und Debug einsetzt, siehst du, dass
die Variable schon gelöscht wurde.
Lars
The only problem with troubleshooting is, that sometimes the trouble shoots back.
P4 2,6Ghz, 512MB RAM, GeForce 6200, WinXP Pro SP2, PB V3.94
Antworten