Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
CommLan
Anmeldungsdatum: 23.10.2015 Beiträge: 40 Wohnort: hinterm Mond
|
Verfasst am: 09.10.2016, 17:49 Titel: REDIM PRESERVE auf ein Array in einem UDT anwenden |
|
|
Hallo an alle ins Forum,
auch heute hab ich etwas, wo ich gerade am verzweifeln bin, weil es für mich schon nahezu Brainfuck ist.
Dieses mal geht es darum, ein in einem UDT liegendes Array variabel zu vergrößern. Eine weitere Kunst ist, dass das UDT selbst auch als Array fungiert.
Hier mal ein Beispielcode, der das Problem erläutern soll:
Code: |
'Das UDT mit dem Array
TYPE Udt
DIM AS INTEGER ArrayElementCount = 5
REDIM AS INTEGER Array(5) '5 Elemente im Array (Eig. 6)
END TYPE
'Eindimensionales Array mit dem UDT erstellen
REDIM AS Udt MyUdt(10)
|
Das wäre jetzt mein Ansatz mit REDIM, er funktioniert aber irgendwie nicht...
Code: |
'Array in dem UDT erweitern
MyUdt(0).ArrayElementCount = 6
REDIM PRESERVE AS INTEGER MyUdt(5).Array(6) 'Array auf 6 Elemente erweitern (eig. 7)
|
Hinweis: ArrayElementCount gibt nur an, wie viele Elemente in dem besagten Array im UDT liegen (Damit ich es nicht erst noch wieder herausfinden muss). Zudem, der Code ist soweit für Tests ausführbar (Bis auf meinen Ansatz halt)
Jetzt ist die Frage, geht das überhaupt mit REDIM (Was mir lieb wäre ) oder muss ich mir im UDT eine Funktion erstellen, die das in der UDT - Ebene mit REDIM managed (Was nicht so super wäre ) ? |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4599 Wohnort: ~/
|
Verfasst am: 09.10.2016, 18:42 Titel: |
|
|
Wenn du ein dynamisches Array in ein UDT legen willst, muss die Dimensionenzahl festgelegt werden. Bei einem eindimensionalen Array:
Code: | 'Das UDT mit dem Array
TYPE Udt
DIM AS INTEGER ArrayElementCount = 5
REDIM AS INTEGER Array(ANY) ' <== ANY (DIM statt REDIM geht auch)
END TYPE
REDIM AS Udt MyUdt(10)
'Array in dem UDT erweitern
MyUdt(0).ArrayElementCount = 6
REDIM PRESERVE (MyUdt(5).Array)(6) ' <== Klammerung beachten
FOR i AS INTEGER = LBOUND(MyUdt) TO UBOUND(MyUdt)
PRINT UBOUND(MyUdt(i).Array)
NEXT
GETKEY |
Ob das mit dem PRESERVE bei der Verschachtelung noch funktioniert, musst du ausprobieren. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1212 Wohnort: Ruhrpott
|
Verfasst am: 09.10.2016, 19:15 Titel: |
|
|
Hallo CommLan!
So funktioniert es:
Code: |
'Das UDT mit dem Array
TYPE Udt
DIM AS INTEGER ArrayElementCount = 5
REDIM AS INTEGER Array(5) '5 Elemente im Array (Eig. 6)
END TYPE
'Eindimensionales Array mit dem UDT erstellen
REDIM AS Udt MyUdt(10)
With myudt(5) 'zur Kontrolle
For x As Integer = LBound (.array) To UBound(.array)
.array(x) = 100 + x
Next
End With
'Array in dem UDT erweitern
MyUdt(0).ArrayElementCount = 6
With myudt(5)
ReDim Preserve .array(6)
End With
'Obergrenzen von "Array()"
For x As Integer = LBound(myudt) To UBound(myudt)
Print x;" ";UBound(myudt(x).array)
Next
Print
'Inhalte von MyUDT(5).Array(x)
With myudt(5)
For x As Integer = LBound(.array) To UBound(.array)
Print x;" ";.array(x)
Next
End With
Sleep |
Gruß
grindstone
EDIT:
Da war nemored mal wieder schneller! Aber dafür zeigt mein Beispiel, daß Preserve tatsächlich funktioniert. _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
CommLan
Anmeldungsdatum: 23.10.2015 Beiträge: 40 Wohnort: hinterm Mond
|
Verfasst am: 09.10.2016, 19:34 Titel: |
|
|
Danke für eure Hilfe
Hab jetzt erstere Lösung von nemored ohne Kontrollen umgesetzt mit REDIM und dem Klammerbrainfuck (Weil es bei mir nicht anders nötig ist und nicht noch komplexer werden darf durch Unterstrukturen). Und was soll ich sagen, bis jetzt geht es.
PRESERVE funktioniert übrigens bisher in der Unterebene noch einwandfrei
@Grindstone: Deine Variante ist sicher die Lösung die sicherer und "richtiger" ist, aber die Komplexität ist bei mir schon ziemlich hoch und da ist die erste Lösung doch trivialer
Nebenbei: Hier geht es nämlich um einen Compiler für eine neue Sprache der schon so komplex genug ist gerade |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1212 Wohnort: Ruhrpott
|
Verfasst am: 09.10.2016, 20:12 Titel: |
|
|
CommLan hat Folgendes geschrieben: | Deine Variante ist sicher die Lösung die sicherer und "richtiger" ist, |
Da muß ich dir -zumindest teilweise- widersprechen.
nemoreds Lösung ist genauso "richtig" wie meine, nur halt anders codiert. Das Konstrukt mit "WITH" dient hauptsächlich dazu, bei langen Bezeichnern die Tipparbeit zu vereinfachen und die Lesbarkeit zu verbessern. Andererseits entstehen dabei -wie du ganz richtig bemerkt hast- zusätzliche Unterstrukturen. Was jeweils besser oder schlechter ist, hängt vom Einzelfall ab und auch von den persönlichen Präferenzen des Programmierers.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4599 Wohnort: ~/
|
Verfasst am: 09.10.2016, 22:28 Titel: |
|
|
Das Problem bei dem "Klammerbrainfuck" ist halt, dass der Compiler wissen muss, was du von ihm willst, und wenn da
Code: | REDIM PRESERVE MyUdt(5).<nochirgendwas> |
steht, denkt er, er soll MyUdt redimensionieren, und was da hinter dem Punkt steht, ergibt dann keinen Sinn mehr für ihn. Der Zugriffsoperator hat hier eine niedrigere Priorität als die Indizierung.
(https://www.freebasic-portal.de/befehlsreferenz/ausdruecke-operatoren-384.html)
Mit den Klammern ist das klar, weil erst der Klammerausdruck ausgewertet wird und dann erst <ausgewerteterAusdruck>.Array in das REDIM geschoben wird.
Mit WITH wird das Problem umgangen; auch hier ist dem Compiler dann klar, was genau er redimensionieren soll, aber deswegen ist jetzt keine der beiden Lösungen richtiger oder falscher. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
|