 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Weazle25
Anmeldungsdatum: 04.11.2007 Beiträge: 18 Wohnort: Stralsund (Mecklenburg-Vorpommern)
|
Verfasst am: 02.03.2008, 18:14 Titel: Verschiedene Datentypen im gleichen Speicherfeld speichern? |
|
|
Wie kann man verschiedene (einfache) Datentypen in ein und dem selben Speicherfeld speichern bzw aus selbigem auslesen?
Grund: Ich möchte meine Daten künftig komprimiert auf der Festplatte speichern.
Dazu müssen die komprimierten Daten in ein Speicherfeld gelesen und dort dekomprimiert werden.
Anschliessend werden die Daten aus diesem Speicherfeld ausgelesen.
Das De-/Komprimieren klappt mittlerweile problemlos.
Das Problem ist aber das auslesen der Daten.
Bisher habe ich das Speicherfeld als UByte PTR deklariert und Shorts/Ints beim Lesen/Speichern in einzelne Bytes zerlegt bzw. aus einzelnen Bytes zusammen gesetzt.
Floats musste ich um das Runden zu unterbinden bisher sogar Bitweise kopieren.
Daher meine Frage: Gibt es dafür eine einfachere Lösung?
Ich stelle mir das etwa wie bei BlitzBasic vor:
Bank = CreateBank( Size ) -> entspricht in etwa Allocate bzw. Callocate
Byte = PeekByte( Bank, Offset )
Short = PeekShort( Bank, Offset )
Float = PeekFloat( Bank, Offset )
PokeByte( Bank, Offset, Byte )
PokeFloat( Bank, Offset, Float )
Gibt es so etwas auch in FreeBasic?
Oder wie kann man das in FreeBasic umsetzen?
Gruss
Weazle |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 03.03.2008, 00:27 Titel: |
|
|
es gibt ein Äquivalent zu structs in C, die Types (mit der Erweiterung um funktionspointer):
TYPE foo
bar1 AS INTEGER
bar2 AS STRING
END TYPE
zB zu benutzen als
DIM obj AS foo
obj.bar1 = 2
obj.bar2 = "hallo"
schau dazu vllt mal in die Referenz.
Und Arrays gibts auch:
DIM array(maxIndex) AS type
zB
DIM feld(4) AS foo
feld(3) = obj
IF feld(4)=obj THEN PRINT "42"
suchst du sowas? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Weazle25
Anmeldungsdatum: 04.11.2007 Beiträge: 18 Wohnort: Stralsund (Mecklenburg-Vorpommern)
|
Verfasst am: 03.03.2008, 01:12 Titel: |
|
|
@MisterD
Das ist leider nicht was ich suche.
Vielleicht habe ich mich etwas unglücklich ausgedrückt.
Ich will mit Allocate ein Speicherfeld erstellen und in diesem Speicherfeld Variablen mit verschiedenen Datentypen speichern.
Beispiel: (Pseudo-Code)
Bank = Allocate( 100 )
Offset = 0
PokeUByte( Bank, Offset, 200 )
Offset = 1
PokeUShort( Bank, Offset, 39217 )
Offset = 3
PokeUInteger( Bank, Offset, 1234567890 )
Offset = 7
PokeDouble( Bank, Offset, 37.45 )
Ich hoffe das das jetzt verständlicher ist.
Gruss
Weazle |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 03.03.2008, 05:03 Titel: |
|
|
TYPE bank
wert1 AS UBYTE
wert2 AS USHORT
wert3 AS UINTEGER
wert4 AS DOUBLE
END TYPE
DIM myBank AS bank
WITH myBank
.wert1 = 200
.wert2 = 39217
.wert3 = 1234567890
.wert4 = 37.45
END WITH
oder meinst du, dass du die typen auch noch runtime ändern können willst? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 03.03.2008, 10:08 Titel: |
|
|
Dim pFOO as ANY Ptr
"ANY" erlaubt es, daß der Pointer auf jede Art von Datentyp, einschließlich userdefinierte Datentypen- zeigen kann. Allerdings, bevor Du allociierst, sollte das Programm genau wissen, wieviel Speicher es braucht. D. h. die Variablen, für die Du Speicher allociierst, sollten bis dahin fertig gefüllt sein.
[Edit] Ist für Deine Belange aber ungeeignet. Ein allociierter Datentyp muß einen entsprechenden Pointer haben.
Was ist mit UNION? _________________ Und die Grundgebihr is aa scho drin- DOS is jo nett. |
|
Nach oben |
|
 |
Weazle25
Anmeldungsdatum: 04.11.2007 Beiträge: 18 Wohnort: Stralsund (Mecklenburg-Vorpommern)
|
Verfasst am: 03.03.2008, 13:19 Titel: |
|
|
Also noch mal zum mitschreiben
Ich will nix über UDT's oder Arrays wissen sondern über Speicherfelder die mit Allocate bzw. Callocate erstellt werden.
In der Online-Hilfe habe ich dazu dieses Beispiel gefunden:
Code: |
' Platz für 15 INTEGER-Speicherstellen reservieren
CONST IntegerCount AS INTEGER = 15
DIM AS INTEGER PTR buffer
buffer = ALLOCATE( IntegerCount * LEN( INTEGER ) )
IF( buffer = 0 ) THEN
' Reservierung schlug fehl wenn PTR = 0
PRINT "Fehler: Speicher konnte nicht reserviert werden"
END -1
END IF
' Fibonacci-Sequenz einleiten
buffer[ 0 ] = 0
buffer[ 1 ] = 1
DIM AS INTEGER i
' ..., vervollständigen...
FOR i = 2 TO IntegerCount - 1
buffer[ i ] = buffer[ i - 1 ] + buffer[ i - 2 ]
NEXT
' ... und ausgeben
FOR i = 0 TO IntegerCount - 1
PRINT buffer[ i ] ;
NEXT
' Speicher wieder freigeben
DEALLOCATE( buffer )
' Programm beenden
END 0
|
Jetzt ist das Speicherfeld aber auf Integer fest genagelt.
Ich will aber verschiedene Datentypen gleichzeitig in diesem Speicherfeld speichern.
Wenn ich nun
Code: |
DIM AS INTEGER PTR buffer
|
durch
Code: |
DIM AS Any PTR buffer
|
ersetze und dann mit
darauf zu greife sagt Freebasic das die Deklaration unvollständig sei.
Also wie muss ich das jetzt machen?
Gruss
Weazle |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 03.03.2008, 13:27 Titel: |
|
|
TYPE bank
wert1 AS INTEGER
wert2 AS STRING
END TYPE
DIM AS bank PTR buffer
buffer = ALLOCATE(4*sizeof(bank))
buffer[3].wert1=200
buffer[3].wert2="hallo"
DEALLOCATE(buffer)
Damit FB auf irgendwas zugreifen kann muss es den Datentyp des Speicherobjekts kennen, ANY ist ein nicht definierter Datentyp -> geht nicht. Also entweder musst du dir dann von Hand merken, was wo steht, oder du definierst deinen Speicherbereich als udt-pointer-feld was ja auch geht, siehe oben. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 03.03.2008, 14:27 Titel: |
|
|
Code: | Dim As Any Ptr bank= Allocate(100)
Dim As Integer offs =0
Dim As UByte x
Cast(UByte Ptr,bank)[offs]=200
offs += 1
Cast(Ushort Ptr,bank)[offs]=39217
offs += 2
Cast(Uinteger Ptr,bank)[offs]=1234567890
offs += 4
Cast(double Ptr,bank)[offs]=37.45
offs += 8
offs -= 8
? *(Cast(double Ptr, bank)+offs)
offs -= 4
? *(Cast(Uinteger Ptr, bank)+offs)
offs -= 2
? *(Cast(Ushort Ptr, bank)+offs)
offs -= 1
? *(Cast(UByte Ptr, bank)+offs)
DeAllocate bank
sleep | Das kannst du auch als subs anlegen, ist aber sehr mühsam die Positionen der einzelnen Variablen zu rekonstruiren. _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 03.03.2008, 14:27 Titel: |
|
|
Weazle25 hat Folgendes geschrieben: | Also noch mal zum mitschreiben
Ich will nix über UDT's oder Arrays wissen sondern über Speicherfelder die mit Allocate bzw. Callocate erstellt werden.
Jetzt ist das Speicherfeld aber auf Integer fest genagelt.
Ich will aber verschiedene Datentypen gleichzeitig in diesem Speicherfeld speichern.
Wenn ich nun
Code: |
DIM AS INTEGER PTR buffer
|
durch
Code: |
DIM AS Any PTR buffer
|
ersetze und dann mit
darauf zu greife sagt Freebasic das die Deklaration unvollständig sei.
Also wie muss ich das jetzt machen?
Gruss
Weazle |
Dann wirst Du um UDTs oder Unions nicht herumkommen. Um Speicher mit Allocate/Callocate zu reservieren, mußt Du Allocate die genaue Größe (per X*LEN(Variable)) des Speicherbereiches übergeben. Dann kannst Du per Pointer darauf zugreifen, aber nur mit dem Pointer des Variablentyps, der in dem Speicherbereich abgelegt ist. Wenn Du mehrere verschiedene Variablen brauchst, geht das nur über ein Type (UDT). _________________ Und die Grundgebihr is aa scho drin- DOS is jo nett. |
|
Nach oben |
|
 |
Cherry
Anmeldungsdatum: 20.06.2007 Beiträge: 249
|
Verfasst am: 03.03.2008, 14:33 Titel: |
|
|
Meinst du sowas?
Code: | #define MB *1048576
Dim bank As Any Ptr = CAllocate(2 MB) ' 2 MB reservieren
Dim position As Integer = 0
' Daten speichern
*Cast(Byte Ptr, bank + position) = 123: position += SizeOf(Byte)
*Cast(Short Ptr, bank + position) = 12345: position += SizeOf(Short)
*Cast(Integer Ptr, bank + position) = 1234567: position += SizeOf(Integer)
' Daten laden (und mit Print anzeigen)
position = 0
Print *Cast(Byte Ptr, bank + position): position += SizeOf(Byte)
Print *Cast(Short Ptr, bank + position): position += SizeOf(Short)
Print *Cast(Integer Ptr, bank + position): position += SizeOf(Integer)
' Speicher freigeben
DeAllocate(bank)
Sleep |
|
|
Nach oben |
|
 |
Weazle25
Anmeldungsdatum: 04.11.2007 Beiträge: 18 Wohnort: Stralsund (Mecklenburg-Vorpommern)
|
Verfasst am: 03.03.2008, 15:33 Titel: |
|
|
Ich bin gerade in der Online-Hilfe über Peek und Poke gestolpert und da kam mir folgendes in den Sinn:
Code: |
Dim Bank As Any Ptr
Bank = callocate( 100 )
Dim _Offset As UInteger = 10
Dim Value1 As Byte = 75
Dim Value2 As Short
Poke Byte, Bank + _Offset, Value1
Value2 = Peek( Short, Bank + _Offset )
|
Das wäre genau das was ich suche.
Jetzt muss ich nur mal schauen ob das auch funktioniert.
Gruss
Weazle |
|
Nach oben |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 03.03.2008, 15:56 Titel: |
|
|
Weazle25 hat Folgendes geschrieben: | Ich bin gerade in der Online-Hilfe über Peek und Poke gestolpert und da kam mir folgendes in den Sinn:
Code: |
Dim Bank As Any Ptr
Bank = callocate( 100 )
Dim _Offset As UInteger = 10
Dim Value1 As Byte = 75
Dim Value2 As Short
Poke Byte, Bank + _Offset, Value1
Value2 = Peek( Short, Bank + _Offset )
|
Das wäre genau das was ich suche.
Jetzt muss ich nur mal schauen ob das auch funktioniert.
Gruss
Weazle |
Siehe dazu die FB-Hilfe:
Zitat: |
Mit PEEK und POKE wurden in älteren BASIC-Dialekten Pointer-Funktionen erstellt.
Beispiel: Wert dreier Variablen aus dem Speicher lesen:
Code: |
DIM ByteVal AS BYTE, ShortVal AS SHORT, IntVal AS INTEGER
DIM AS INTEGER ByteAddr, ShortAddr, IntAddr
ByteAddr = VARPTR(ByteVal)
ShortAddr = VARPTR(ShortVal
IntAddr = VARPTR(IntVal)
ByteVal = 127
ShortVal = 32767
IntVal = 2 ^ 31 - 1
PRINT ByteVal, ShortVal, IntVal
PRINT PEEK(BYTE, ByteAddr), PEEK(SHORT, ShortAddr), PEEK(INTEGER, IntAddr)
|
Diese Form funktioniert einwandfrei. FreeBASIC hat jedoch eigene Pointer-Funktionen,
die ein komfortableres Programmieren ermögichen. Mit den FB-eigenen Funktionen würde dieses Beispiel so aussehen:
Code: |
DIM ByteVal AS BYTE, ShortVal AS SHORT, IntVal AS INTEGER
DIM BytePtr AS BYTE PTR, ShortPtr AS SHORT PTR, IntPtr AS INTEGER PTR
BytePtr = @ByteVal
ShortPtr = @ShortVal
IntPtr = @IntVal
ByteVal = 127
ShortVal = 32767
IntVal = 2 ^ 31 - 1
PRINT ByteVal, ShortVal, IntVal
PRINT *BytePtr, *ShortPtr, *IntPtr
|
Die Syntax *Pointer gibt also den Wert zurück, der an der Speicherstelle steht, auf die der Pointer zeigt. Wie viele Bytes
gelesen werden, hangt dabei vom Typ des Pointers ab (BYTE PTR, SINGLE PTR, ...)
|
Der Zugriff über Pointer oder über Poke ist demnach gleichwertig. _________________ Und die Grundgebihr is aa scho drin- DOS is jo nett. |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|