Dinge, die ich nicht wusste

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

es geht ja nicht ums ende , sondern um die benutzung dieser Variante in einem Code. :|

es reicht ja nicht ein FreeMemory(*Test), sonder er muss es immer machen bevor er den "alten" Pointer überschreibt, um ihn nicht zu verlieren.
:wink:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Ich mach das schon absichtlich so... die paar Bytes kann der Arbeitsspeicher schon verschmerzen... :mrgreen:

Wenn ich das nur mit Pointern mache ohne CopyMemory() zeigt der Pointer ja nur auf die Adresse der Variable in der Procedure. Wenn ich nun die funktion ein 2. mal aufrufe und sich die Werte der Variable ändern zeigen alle früheren Ergebnisse immer noch auf diesen Speicher und alle früheren Erg. ändern sich auch:

Code: Alles auswählen

Structure MyStruct


  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  tVar.MyStruct
  tVar\Val1 = 1233*2
  tVar\Val2 = 124124*2
  tVar\Val3 = 1212.213123*2
  tVar\Val4 = 1233.123321*2
  ProcedureReturn @tVar
EndProcedure

*Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4

*Test3.MyStruct = Return4Values(3)

Debug *Test3\Val1
Debug *Test3\Val2
Debug *Test3\Val3
Debug *Test3\Val4

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
Wenn ich das ganze in einer Schleife mache gebe ich sowiso immer den alten Speicher vorher frei, das muss man dann halt manuel machen.
Zuletzt geändert von cxAlex am 27.09.2008 19:35, insgesamt 1-mal geändert.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

STARGÅTE hat geschrieben:es geht ja nicht ums ende , sondern um die benutzung dieser Variante in einem Code. :|

es reicht ja nicht ein FreeMemory(*Test), sonder er muss es immer machen bevor er den "alten" Pointer überschreibt, um ihn nicht zu verlieren.
:wink:
Ja eben... aber hier ist ja kein alter Pointer, hier ist nur einer. Es steht ja auch nicht im Anfänger-Forum sondern in "Code, Tipps und Tricks".
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

So hier eine ERLAUBTE ( :lol: :lol: ) Version meines Codes:

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure

Macro ReturnStruct(_Var, _Struct)
  *tMem = AllocateMemory(SizeOf(_Struct))
  CopyMemory(@_Var, *tMem, SizeOf(_Struct))
  ProcedureReturn *tMem
EndMacro

Macro GetStructValue(_Function,_Var,_Struct)
  *tMem = _Function
  CopyMemory(*tMem, @_Var, SizeOf(_Struct))
  FreeMemory(*tMem)
EndMacro


Procedure Return4Values()
  tVar.MyStruct
  tVar\Val1 = 1233
  tVar\Val2 = 124124
  tVar\Val3 = 1212.213123
  tVar\Val4 = 1233.123321
  ReturnStruct(tVar, MyStruct)
EndProcedure

GetStructValue(Return4Values(),Test.MyStruct,MyStruct)

Debug Test\Val1
Debug Test\Val2
Debug Test\Val3
Debug Test\Val4
Jetzt wird der alte Speicher immer Freigegeben.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  Static tVar.MyStruct
  tVar\Val1 = 1233*x
  tVar\Val2 = 124124*x
  tVar\Val3 = 1212.213123*x
  tVar\Val4 = 1233.123321*x
  ProcedureReturn @tVar
EndProcedure

Define *Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
reicht das nicht?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

ts-soft hat geschrieben:

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  Static tVar.MyStruct
  tVar\Val1 = 1233*x
  tVar\Val2 = 124124*x
  tVar\Val3 = 1212.213123*x
  tVar\Val4 = 1233.123321*x
  ProcedureReturn @tVar
EndProcedure

Define *Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
reicht das nicht?
Wenn sich da jetzt nichts in PureBasic in den nächsten 10 Versionen ändert reicht das. Aber du weißt nie ob Static Variablen plötzlich anders ausgelagert werden.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

So verlierst du aber die alten Werte:

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  Static tVar.MyStruct
  tVar\Val1 = 1233*x
  tVar\Val2 = 124124*x
  tVar\Val3 = 1212.213123*x
  tVar\Val4 = 1233.123321*x
  ProcedureReturn @tVar
EndProcedure

Define *Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4

Define *Test2.MyStruct = Return4Values(3)

Debug *Test2\Val1
Debug *Test2\Val2
Debug *Test2\Val3
Debug *Test2\Val4

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
Weil alle Werte auf den selben Speicher zeigen.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

Was ist eigentlich gegen die Übergabe der Struktur die die Daten erthalten soll zu sagen? Das wäre Speichermäßig doch die sauberste Lösung.

Code: Alles auswählen

procedure ByRef(*Output.outputstruct)
*Output\Value1 = #Wasweissich
  ; ...
  ProcedureReturn 1
EndProcedure

ByRef(Out.outputstruct)
; ...
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Beitrag von Josef Sniatecki »

@Batze: Dieser weg ist schon gut. Jedoch ist dies nur nützlich für mehrere
Rückgabewerte auf ein Mal. Man sollte möglichst komplexe Ausdrücke
erlauben wie: "x=int(y)+5"
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Wenn das hier ein Anfänger liest, wird er wenig bis nix kapieren, es ist aber gerade für Anfänger wichtig.

in meinen Augen gibt es nur einen korrekten Weg, wenn man Werte übergeben will und diese in einer Prozedur ändern will und anschließend mit diesen geänderten Werten weiterarbeiten will.

Man packe alles in eine Struktur, definiere eine Variable und übergebe diese an eine Prozedur

Abgesehen davon ist dies doch ein altes Thema, die Rückgabe eines Zeigers mit ProcedureReturn der auf eine Variable zeigt, welche in der Prozedur definiert wird, ist Unsinn und wie TSSOFT sagte verboten. Und zwar weil lokale Variablen nach verlassen der Prozedur früher oder später gelöscht bzw. überschrieben werden und der Zeiger dann auf sonstwas zeigt.
Ausser man macht es wie TSSOFT und erklärt diese Variable als Static, nur ist das nicht besonders flexibel.

Hier mal BATZE seinen Beitrag etwas ausführlicher

Code: Alles auswählen

Declare Return4Values(*tVar, x) 
Declare Return4Values2(*tVar, x) 
Declare Return4Values3(*tVar, *tVar2, x) 
Declare Return4Values4(*tvar, x$) 

Structure MyStruct 
  Val1.l 
  Val2.l 
  Val3.d 
  Val4.d 
EndStructure 

;----------------------------------

With Test.MyStruct
  
  \Val1 = 1233
  \Val2 = 124124 
  \Val3 = 1212.213123 
  \Val4 = 1233.123321 

  Return4Values(Test, 2) 

EndWith

Debug Test\Val1 
Debug Test\Val2 
Debug Test\Val3 
Debug Test\Val4 

;oder mit festen Werten in der Prozedur

Return4Values2(Test2.MyStruct, 3) 

Debug Test2\Val1 
Debug Test2\Val2 
Debug Test2\Val3 
Debug Test2\Val4 

;Noch eine Variante mit einer bzw. mehreren Variablen

Return4Values3(@Test3.l, @Test4.d, 3) 

Debug Test3
Debug Test4

;oder mit variablen Strings, es geht aber nur so
;also nicht mit Test5$ oder Test5.s

Return4Values4(Test5.String, "dreifacher") 

Debug Test5\s

End

;-----------------------------------------

Procedure Return4Values(*t.MyStruct, x) 

With *t
  \Val1 * x 
  \Val2 * x 
  \Val3 * x 
  \Val4 * x 
EndWith
   
EndProcedure 

Procedure Return4Values2(*t.MyStruct, x) 

With *t
  \Val1 = x * 1233
  \Val2 = x * 124124 
  \Val3 = x * 1212.213123 
  \Val4 = x * 1233.123321 
EndWith
   
EndProcedure 

Procedure Return4Values3(*v1.long, *v4.double, x) 

  *v1\l = x * 1233
  *v4\d = x * 1233.123321 
   
EndProcedure 

Procedure Return4Values4(*v1.string, x$) 
  
  *v1\s = "Hallo, du " + x$ + " Meuchelmörder" 
   
EndProcedure 


Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Antworten