Integerübergabe ByRef

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Integerübergabe ByRef

Beitrag von Kurzer »

Hallo zusammen,

nachdem ich seit ein paar Wochen in PHP eine Webanwendung programmiere, bin ich durch dessen Möglichkeiten etwas verwöhnt wie mir scheint. ;-)

"Nativ" werden in PureBasic ja nur Arrays, Listen und Maps als Referenz an Prozeduren übergeben.

In PHP kann jede Variable sehr einfach, nach Bedarf "byRef" übergeben (oder besser aus Sicht der Funktion "übernommen") werden, wenn man bei der Funktionsimplementation ein & vor die Variable schreibt.

Code: Alles auswählen

function Test($param1, &$param2) {
    $param2 = 22;
}

$a = 10;
echo test(1, $a);
echo a$;   // Wird 22 ausgeben
Param 2 wird dadurch automatisch "byRef" behandelt, also als Referenz auf die originale Variable außerhalb der Prozedur / Funktion.

Nun habe ich mir das in PureBasic wie folgt nachgebaut und frage mich, ob das die einzige Möglichkeit ist dies zu erreichen.

Code: Alles auswählen

Procedure test (*byref.integer)
			*byref\i = 22
EndProcedure
	
a.i = 10
test (@a)

Debug a ; gibt 22 aus.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Integerübergabe ByRef

Beitrag von GPI »

das einzige, was mir noch einfällt, wäre Macros zur Verschleierung zu Nutzen.

Code: Alles auswählen

Procedure __test (*byref.integer)
  *byref\i = 22
EndProcedure
Macro test(variable)
  __test(@variable)
EndMacro


a.i = 10
test (a)

Debug a ; gibt 22 aus.
Macht aber den Code etwas schlechter lesbar.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Integerübergabe ByRef

Beitrag von mk-soft »

Schwieriger wird es bei Strings als ByRef zu übergeben.
Es kann nicht eine einfache String-Variable übergeben werden weil dann der Pointer zum String übergeben wird und nicht der Pointer zur Variable der den Pointer zum String enthält.

Code: Alles auswählen

;-TOP
Procedure foo(*inout.String, *value.integer)
  *value\i + 100
  *inout\s + " " + Str(*value\i)
EndProcedure

Global t1.String
Global v1 = 100
t1\s = "hello world"
Debug "Address of String: " + PeekI(t1)
Debug t1\s
foo(t1, @v1)
Debug "Address of String: " + PeekI(t1)
Debug t1\s

; Invalid Pointer to String

t2.s = "hello world"
Debug "Address of String: " + PeekI(@t2)
foo(@t2, @v1)
Debug "Address of String: " + PeekI(@t2)
Debug t2
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: Integerübergabe ByRef

Beitrag von uweb »

Das ist ja mal eine nette Denksportaufgabe für den Sonntagmorgen.

*byref.integer kannte ich noch gar nicht.
Deswegen habe ich eine noch schlechter lesbare Lösung gebastelt.
Die ist zwar viel aufwendiger, aber wenn man schon von hinten durch die Brust ins Auge fasst sind Strings auch kein Problem mehr.
Ob das nun sinnvoll ist steht auf einem anderen Blatt.
:)

Code: Alles auswählen

Structure Param
  int.i
  strg .s
EndStructure

; Die Grundidee ist es von Anfang an Felder statt Variablen zu nutzen:
Dim parameters.Param(1)
Macro a_i : parameters(1)\int : EndMacro
Macro hi_s : parameters(1)\strg : EndMacro

Macro params : Array parameters.Param(1) : EndMacro ; nur verkürzte Schreibweise
Declare Test(params)

Macro TestParam1 : parameters(0)\int : EndMacro
Macro TestParam2 : parameters(1)\int : EndMacro
Macro TestParam3 : parameters(0)\strg : EndMacro
Macro TestParam4 : parameters(1)\strg : EndMacro

Macro _Test(_TestParam1, _TestParam2, _TestParam3, _TestParam4)
  ; da auch Konstanten übergeben werden können:
  parameters(0)\int=_TestParam1
  parameters(1)\int=_TestParam2
  parameters(0)\strg=_TestParam3
  parameters(1)\strg=_TestParam4
  Test(parameters())
EndMacro


Procedure Test (params)
  TestParam2 = 22;
  a_i = a_i + TestParam1 ; Das Macro für a_i ist global
  TestParam4 = TestParam4 + TestParam3
EndProcedure


a_i = 10
hi_s = "Hello World!"
_Test(1, a_i," Nice to meet you.",hi_s)
Debug a_i
Debug hi_s
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Integerübergabe ByRef

Beitrag von Nino »

Kurzer hat geschrieben:"Nativ" werden in PureBasic ja nur Arrays, Listen und Maps als Referenz an Prozeduren übergeben.
uweb hat geschrieben:

Code: Alles auswählen

; Die Grundidee ist es von Anfang an Felder statt Variablen zu nutzen:
Also Arrays (bzw. Listen oder Maps) nur deshalb benutzen, weil sie als Prozedurparameter als Referenz übergeben werden, auch wenn man sie sonst gar nicht braucht?
uweb hat geschrieben:Ob das nun sinnvoll ist steht auf einem anderen Blatt.
:)
Jo. :-) Da würde ich doch lieber Zeiger nehmen, so wie hier im 1. Posting gezeigt.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Integerübergabe ByRef

Beitrag von GPI »

Nino hat geschrieben:Also Arrays (bzw. Listen oder Maps) nur deshalb benutzen, weil sie als Prozedurparameter als Referenz übergeben werden, auch wenn man sie sonst gar nicht braucht?
Structuren gehen auch wunderbar

Code: Alles auswählen

Structure para
  opt1.i
  opt2.s
  opt3.d
EndStructure

v.para
v\opt1=10
v\opt2="test"
v\opt3=4.5

Procedure test(*para.para)
  Debug "test:"+*para\opt1+" "+*para\opt2+" "+*para\opt3
  *para\opt1=33
  *para\opt2="neo"
  *para\opt3=9.9
EndProcedure

Debug "outside:"+v\opt1+" "+v\opt2+" "+v\opt3

test(v)

Debug "outside:"+v\opt1+" "+v\opt2+" "+v\opt3
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Integerübergabe ByRef

Beitrag von Nino »

GPI hat geschrieben:
Nino hat geschrieben:Also Arrays (bzw. Listen oder Maps) nur deshalb benutzen, weil sie als Prozedurparameter als Referenz übergeben werden, auch wenn man sie sonst gar nicht braucht?
Structuren gehen auch wunderbar
Ja klar, die hat Kurzer ja von Anfang an verwendet. :-)

Code: Alles auswählen

.integer
bezeichnet nichts anderes als eine in PB bereis eingebaute Struktur. Natürlich bietet es sich je nach Situation an, ggf. best. "by Reference-Variablen" in einer selbstdefinierten Struktur zusammenzufassen.
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Integerübergabe ByRef

Beitrag von Kurzer »

Ich versuche die PHP Syntax gerade mit Macros zu imitieren, es scheitert aber daran, dass das Verkettungs-Zeichen # in Macros nicht mit einem * zusammen funktioniert.

http://www.purebasic.fr/english/viewtop ... 13&t=68850
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: Integerübergabe ByRef

Beitrag von uweb »

Code: Alles auswählen

a_i = 10
hi_s = "Hello World!"
_Test(1, a_i," Nice to meet you.",hi_s)
Nach reichlichem Herumprobieren bin ich auf noch keine bessere Lösung für ByRef und Konstanten gekommen.
Mir ist schon klar, dass die Array-Lösung umständlich ist und nur fuktioniert weil sie die Konstantenwerte in ein Feld kopiert - also die Konstanten nicht wirklich ByRef behandelt.
Aber was wäre denn der bessere Weg ohne die Syntax zu vergewaltigen bzw um sie ggf. über Makros wiederherzustellen?

PS
Ich habe gerade beim Aufräumen noch etwas witziges wiedergefunden:

Code: Alles auswählen

Procedure _test (*byref1.integer, *byref2.integer)
  *byref2\i = 22
EndProcedure

Macro test(variable1, variable2)
  _test(@variable1, @variable2)
EndMacro

a.i = 10
test (1, a)
Debug a
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Integerübergabe ByRef

Beitrag von Josh »

Gerade zu Beginn meiner Pb-Zeiten war ich von der Parameterübergabe 'ByRef' in Pb auch nicht gerade begeistert.

Trotzdem halte ich nicht viel davon, wenn per Macro syntaktischer Zucker verstreut wird. Das macht es nur mühsamer, wenn nach ein paar Jahren ein Code angepasst werden muss oder gar der Code von anderen gelesen werden muss.
Antworten