DELETE

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
jear
Beiträge: 288
Registriert: 17.10.2004 01:59
Wohnort: Ammerland

Re: Variable freigeben

Beitrag von jear »

es_91 hat geschrieben:Was haltet ihr von der Idee, alle Variablen des Hauptprogramms in eine Funktion zu packen und diese, nennen wir sie main() oder init(), einmal aufzurufen? Dann fehlen zwar globale Variablen, aber von deren Verwendung wird einem ja fast überall abgeraten...
Das ist eine gute Idee und das wird so in vielen größeren Anwendungen realisiert sein. Dabei ist aber offen, was Du nun mit einer "Funktion packen" meinst.

Ein Include zB. wäre nur ein Einschub der Quelle beim Übersetzen. Diese Technik fördert aber die Übersichtlichkeit in den Quellen. Mit welchen Scope dann die Variablen definiert werden, ist von den Überlegungen des Erstellers abhängig.

Auch in einer Prozedur kann man globale Variablen definieren. Eine Prozedur macht aber wenig Sinn, denn sie dürfte ja ohnehin nur ein einziges Mal aufgerufen werden.
es_91 hat geschrieben:]So, dann erkläre, warum 'Variablen oder andere Programm-Elemente' nicht deinitialisiert werden können oder sollten!
Sie auch wenig Sinn, wegen des möglichen Gewinns von SizeOf(Variable)-Bytes komplizierte Mechanismen in eine Sprache zu implementieren. Es müsste ja zur Laufzeit bei jeder Variablen immer wieder geprüft werden, ob diese noch besteht.

Wenn man den Inhalt aber "vergessen" will, genügt es ja die Variable zu löschen/leeren oder mit einem speziellen Inhalt zu füllen.
Man ist nie zu alt zum lernen, auch wenn man dabei manchmal alt aussieht!
Benutzeravatar
CodeCommander
Beiträge: 213
Registriert: 02.03.2014 16:06

Beitrag von CodeCommander »

~ DELETE ~
Zuletzt geändert von CodeCommander am 18.01.2015 14:52, insgesamt 1-mal geändert.
~ DELETE ~
es_91
Beiträge: 410
Registriert: 25.01.2011 04:48

Re: Variable freigeben

Beitrag von es_91 »

jear hat geschrieben:
es_91 hat geschrieben:Was haltet ihr von der Idee, alle Variablen des Hauptprogramms in eine Funktion zu packen[...]
Das ist eine gute Idee und das wird so in vielen größeren Anwendungen realisiert sein. Dabei ist aber offen, was Du nun mit einer "Funktion packen" meinst.
Ja, das war falsch ausgedrückt. Ich meinte eher, das gesammte Hauptprogramm in eine Prozedur zu packen*, und dann, statt im Hauptprogramm, innerhalb der "Wurzelfunktion" zu arbeiten.

* Würde dies nicht einigermaßen den Aufbau eines C-Programmes simulieren?

Mir kam aber auch der Gedanke, dass in Includes, die nicht nur Quelltext innerhalb von Prozeduren enthalten, Variablen im Hauptteil benutzt könnten. Um solche Includes in den von mir vorgeschlagenen Stil umzuwandeln, dürfte man sie nur noch mit XIncludeFile aufrufen. Oder kennt jemand einen Weg, Prozeduren nur dann zu deklarieren und zu definieren, wenn sie noch nicht deklariert und definiert wurden?
jear hat geschrieben:
es_91 hat geschrieben:]So, dann erkläre, warum 'Variablen oder andere Programm-Elemente' nicht deinitialisiert werden können oder sollten!
Sie auch wenig Sinn, [...]
Deutsch, bitte. /:-> :lol:
jear hat geschrieben:Es müsste ja zur Laufzeit bei jeder Variablen immer wieder geprüft werden, ob diese noch besteht.
So meinte ich das nicht. Der Programmierer soll festlegen, wann eine Variable aus dem Speicher entfernt wird, so wie wir das bei Dateien mit CloseFile() machen.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Variable freigeben

Beitrag von NicTheQuick »

es_91 hat geschrieben:Oder kennt jemand einen Weg, Prozeduren nur dann zu deklarieren und zu definieren, wenn sie noch nicht deklariert und definiert wurden?
Siehe 'CompilerIf' und 'Defined':

Code: Alles auswählen

Procedure myProcedure()
	;blabla
EndProcedure

CompilerIf Not Defined(myProcedure, #PB_Procedure)
	; Falls myProcedure noch nicht deklariert oder definiert wurde, definiere sie erneut.
	Procedure myProcedure()
		;blabla
	EndProcedure
	Debug "Erneut definiert."
CompilerEndIf
Und an alle:
Wenn ihr Variablen erstellen und wieder freigeben wollt, dann tut das doch selbst auf dem Heap und fertig. Also nutzt 'AllocateMemory()' oder 'AllocateStructure()' und am Schluss dann eben 'FreeMemory()'. Wenn euch jetzt allerdings noch stören sollte, dass man dafür ja wieder Pointer braucht und man die Pointer nicht mehr "freigeben", dann nutzt einfach C/C++, Java oder was auch immer. Mit PB geht's jedenfalls nicht.
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

Re: Variable freigeben

Beitrag von ts-soft »

Ausserdem ist ja kein Code im MainScope vonnöten. Alles Protected in Proceduren, alle Werte als Parameter übergeben und
schon wird alles freigegeben, am ende der Procedure.

Naja, über Sinn und Zweck läßt sich allerdings streiten :lol:
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
es_91
Beiträge: 410
Registriert: 25.01.2011 04:48

Re: Variable freigeben

Beitrag von es_91 »

[OffTopic]Wieso werde ich nach 5 oder 10 Minuten schon ausgeloggt?

Das ist ja schlimmer, als es für mich war, als ich noch vom Handy gepostet habe...


[/OffTopic]

So, nunmal... eine kleine Umsetzung der Idee, die NicTheQuick uns gab, wenn ich ihn richtig verstanden habe.

Code: Alles auswählen

DeclareModule Vars
  
  Structure Var_Variable
    
    Name$
    Point. Q
    Size. Q
    
  EndStructure
  
  NewList Vars. Var_Variable ()
  
  Declare. Q GetQuad (Name$, Type. B)
  Declare. D GetDouble (Name$, Type. B)
  Declare$ GetString (Name$)
  Declare RegistrateVar (Name$, Type. B, Value$)
  Declare UnregistrateVar (Name$)
  Declare UpdateVar (Name$, Value$)
  
EndDeclareModule

Module Vars
  
  Procedure. Q GetQuad (Name$, Type. B)
    
    Shared Vars ()
    
    ForEach Vars ()
      
      If Vars ()\ Name$ = Name$
        
        Select Type
          
          Case #PB_Ascii
            
            ProcedureReturn PeekA (Vars ()\ Point)
            
          Case #PB_Byte
            
            ProcedureReturn PeekB (Vars ()\ Point)
            
          Case #PB_Character
            
            ProcedureReturn PeekC (Vars ()\ Point)
            
          Case #PB_Integer
            
            ProcedureReturn PeekI (Vars ()\ Point)
            
          Case #PB_Long
            
            ProcedureReturn PeekL (Vars ()\ Point)
            
          Case #PB_Quad
            
            ProcedureReturn PeekQ (Vars ()\ Point)
            
          Case #PB_Unicode
            
            ProcedureReturn PeekU (Vars ()\ Point)
            
          Case #PB_Word
            
            ProcedureReturn PeekW (Vars ()\ Point)
            
        EndSelect
        
      EndIf
      
    Next
    
  EndProcedure
  
  Procedure. D GetDouble (Name$, Type. B)
    
    Shared Vars ()
    
    ForEach Vars ()
      
      If Vars ()\ Name$ = Name$
        
        Select Type
          
          Case #PB_Double
            
            ProcedureReturn PeekD (Vars ()\ Point)
            
          Case #PB_Float
            
            ProcedureReturn PeekA (Vars ()\ Point)
            
        EndSelect
        
      EndIf
      
    Next
    
  EndProcedure
  
  Procedure$ GetString (Name$)
    
    Shared Vars ()
    
    ForEach Vars ()
      
      If Vars ()\ Name$ = Name$
        
        Select Type
          
          Case #PB_String
            
            ProcedureReturn PeekS (Vars ()\ Point)
            
        EndSelect
        
      EndIf
      
    Next
    
  EndProcedure
  
  Procedure RegistrateVar (Name$, Type. B, Value$)
    
    Shared Vars ()
    
    AddElement (Vars ())
    
    Vars ()\ Name$ = Name$
    
    Select Type
      
      Case #PB_Ascii
        
        Vars ()\ Size = 1
        
      Case #PB_Byte
        
        Vars ()\ Size = 1
        
      Case #PB_Character
        
        Vars ()\ Size = StringByteLength (Space (1))
        
      Case #PB_Double
        
        Vars ()\ Size = 8
        
      Case #PB_Float
        
        Vars ()\ Size = 4
        
      Case #PB_Integer
        
        If #PB_Compiler_Processor = #PB_Processor_x64
          
          Vars ()\ Size = 8
          
        Else
          
          Vars ()\ Size = 4
          
        EndIf
        
      Case #PB_Long
        
        Vars ()\ Size = 4
        
      Case #PB_Quad
        
        Vars ()\ Size = 8
        
      Case #PB_String
        
        Vars ()\ Size = StringByteLength (Value$)
        
      Case #PB_Unicode
        
        Vars ()\ Size = 2
        
      Case #PB_Word
        
        Vars ()\ Size = 2
        
    EndSelect
    
    Vars ()\ Point = AllocateMemory (Vars ()\ Size)
    
    Select Type
      
      Case #PB_Ascii
        
        PokeA (Vars ()\ Point, Val (Value$))
        
      Case #PB_Byte
        
        PokeB (Vars ()\ Point, Val (Value$))
        
      Case #PB_Character
        
        PokeC (Vars ()\ Point, Val (Value$))
        
      Case #PB_Double
        
        PokeD (Vars ()\ Point, ValD (Value$))
        
      Case #PB_Float
        
        PokeF (Vars ()\ Point, ValF (Value$))
        
      Case #PB_Integer
        
        PokeI (Vars ()\ Point, Val (Value$))
        
      Case #PB_Long
        
        PokeL (Vars ()\ Point, Val (Value$))
        
      Case #PB_Quad
        
        PokeQ (Vars ()\ Point, Val (Value$))
        
      Case #PB_String
        
        PokeS (Vars ()\ Point, Value$)
        
      Case #PB_Unicode
        
        PokeU (Vars ()\ Point, Val (Value$))
        
      Case #PB_Word
        
        PokeW (Vars ()\ Point, Val (Value$))
        
    EndSelect
    
  EndProcedure
  
  Procedure UnregistrateVar (Name$)
    
    Shared Vars ()
    
    ForEach Vars ()
      
      If Vars ()\ Name$ = Name$
        
        FreeMemory (Vars ()\ Point)
        
        DeleteElement (Vars ())
        
        ProcedureReturn
        
      EndIf
      
    Next
    
  EndProcedure
  
  Procedure UpdateVar (Name$, Value$)
    
    Shared Vars ()
    
    ForEach Vars ()
      
      If Vars ()\ Name$ = Name$
        
        Select Type
          
          Case #PB_Ascii
            
            PokeA (Vars ()\ Point, Val (Value$))
            
          Case #PB_Byte
            
            PokeB (Vars ()\ Point, Val (Value$))
            
          Case #PB_Character
            
            PokeC (Vars ()\ Point, Val (Value$))
            
          Case #PB_Double
            
            PokeD (Vars ()\ Point, ValD (Value$))
            
          Case #PB_Float
            
            PokeF (Vars ()\ Point, ValF (Value$))
            
          Case #PB_Integer
            
            PokeI (Vars ()\ Point, Val (Value$))
            
          Case #PB_Long
            
            PokeL (Vars ()\ Point, Val (Value$))
            
          Case #PB_Quad
            
            PokeQ (Vars ()\ Point, Val (Value$))
            
          Case #PB_String
            
            PokeS (Vars ()\ Point, Value$)
            
          Case #PB_Unicode
            
            PokeU (Vars ()\ Point, Val (Value$))
            
          Case #PB_Word
            
            PokeW (Vars ()\ Point, Val (Value$))
            
        EndSelect
        
        ProcedureReturn
        
      EndIf
      
    Next
    
  EndProcedure
  
EndModule

Macro DefineAscii (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Ascii, Str(Value))
  
EndMacro
Macro DefineByte (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Byte, Str(Value))
  
EndMacro
Macro DefineCharacter (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Character, Str(Value))
  
EndMacro
Macro DefineDouble (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Double, Str(Value))
  
EndMacro
Macro DefineFloat (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Float, Str(Value))
  
EndMacro
Macro DefineInteger (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Integer, Str(Value))
  
EndMacro
Macro DefineLong (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Long, Str(Value))
  
EndMacro
Macro DefineQuad (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Quad, Str(Value))
  
EndMacro
Macro DefineString (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_String, Value)
  
EndMacro
Macro DefineUnicode (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Unicode, Str(Value))
  
EndMacro
Macro DefineWord (Name, Value)
  
  Vars:: RegistrateVar (Name, #PB_Word, Str(Value))
  
EndMacro

Macro FreeVar (Name)
  
  Vars:: UnregistrateVar (Name)
  
EndMacro

Macro SetVar (Name, Value)
  
  Vars:: UpdateVar (Name, Str (Value))
  
EndMacro

Macro ValueOfAscii (Name)
  
  Vars:: GetQuad (Name, #PB_Ascii)
  
EndMacro
Macro ValueOfByte (Name)
  
  Vars:: GetQuad (Name, #PB_Byte)
  
EndMacro
Macro ValueOfCharacter (Name)
  
  Vars:: GetQuad (Name, #PB_Character))
  
EndMacro
Macro ValueOfDouble (Name)
  
  Vars:: GetDouble (Name, #PB_Double)
  
EndMacro
Macro ValueOfFloat (Name)
  
  Vars:: GetDouble (Name, #PB_Float)
  
EndMacro
Macro ValueOfInteger (Name)
  
  Vars:: GetQuad (Name, #PB_Integer)
  
EndMacro
Macro ValueOfLong (Name)
  
  Vars:: GetQuad (Name, #PB_Long)
  
EndMacro
Macro ValueOfQuad (Name)
  
  Vars:: GetQuad (Name, #PB_Quad)
  
EndMacro
Macro ValueOfString (Name)
  
  Vars:: GetString (Name, #PB_String)
  
EndMacro
Macro ValueOfUnicode (Name)
  
  Vars:: GetQuad (Name, #PB_Unicode)
  
EndMacro
Macro ValueOfWord (Name)
  
  Vars:: GetQuad (Name, #PB_Word)
  
EndMacro

Mit diesem Testcode könnt ihr mal euren Speicher ein wenig füllen, nur um zu sehen, wie er sich wieder entleert:

Code: Alles auswählen

For Index = 1 To 4000000
  
  DefineQuad ("Test" + Str (Index), Index)
  
Next

MessageRequester ("", "Vars created. Your program should be using about 400 MB RAM now. We're now going to free the vars. Watch the memory usage.")

For Index = 1 To 4000000
  
  FreeVar ("Test" + Str (Index))
  
Next

MessageRequester ("", "RAM usage should be down to low. Click OK to finish.")

Dabei fällt dem Einen oder Anderen sicher auf: Nach der Ausführung der Variableneliminierung liegen noch etwa 40 MB im Arbeitsspeicher. Woran mag das liegen?

/e: So, Kinderz, und jetzt bitte kein Herumgemaule a lá "Was soll das bringen? Du speicherst zehnmal so viele Daten, wie mit 'normalen' Variablen!"! :wink:
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Variable freigeben

Beitrag von RSBasic »

Bei mir sind es zum Schluss nur 5 MB. Aber falls es hilft: http://www.rsbasic.de/aktualisierung/wi ... eigeben.pb
es_91 hat geschrieben:Wieso werde ich nach 5 oder 10 Minuten schon ausgeloggt?
Domainwechsel oder Cookieproblem?
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
_sivizius
Beiträge: 98
Registriert: 23.10.2013 15:21

Re: Variable freigeben

Beitrag von _sivizius »

Ohai,
Und warum nicht einfach die Variablen wiederverwerten?
Also das mit den Scopes wird auch nur bei Schleifen wirklich genutzt und da fast immer als Counter (z.B. i, j, k, l, ...). Du musst nur die Reihenfolge in der Scope-Tiefe beachten. Für etwas anderes habe ich in Java das eig nie genutzt.
Da solche Scopes aber bei Anfängern häufig zu Problemen führen und Purebasic noch etwas Basic sein will, also einfach zu programmieren, halte ich jene auch nicht für sinnvoll.
mfg
_sivizius
Benutzeravatar
Vera
Beiträge: 928
Registriert: 18.03.2009 14:47
Computerausstattung: Win XP SP2, Suse 11.1
Wohnort: Essen

Re: Variable freigeben

Beitrag von Vera »

es_91 hat geschrieben:[OffTopic]Wieso werde ich nach 5 oder 10 Minuten schon ausgeloggt?
Vielleicht hast Du aus Versehen die alte Forumsaddresse benutzt, von der ein vorzeitiger LogOut schon berichtet wurde.
°
<°)))o><
~~~~~~~~~
echo "Don't worry"
echo "Keep quiet"
@echo off
format forum:\
es_91
Beiträge: 410
Registriert: 25.01.2011 04:48

Re: Variable freigeben

Beitrag von es_91 »

Ach ja, da steht ja jetzt http://www.purebasic.fr in der Adressleiste! Ha, alles klar! :D

Kann mir mal jemand per PN schreiben, seit wann die Neue existiert?
Antworten