Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Kleine Helferlein

Datenfelder (Arrays) mit variabler Größe in UDTs (TYPEs)

Lizenz:Erster Autor:Letzte Bearbeitung:
GPLv3MitgliedTJF 29.06.2013

Eine benutzerdefinierte Datenstruktur (=UDT = user defined type = BefehlsreferenzeintragTYPE Struktur) kann neben einfachen Variablen auch Datenfelder enthalten. Solche Datenfelder können bisher jedoch nur mit fester Länge dimensioniert werden (Stand November 2011 bis fbc-Version 0.23.0 einschließlich). Sie können nicht durch BefehlsreferenzeintragREDIM dynamisch in ihrer Größe verändert werden.

In vielen Fällen ist es jedoch sinnvoll dynamische (variable) Datenfelder einzusetzen, z. B. um unnötigen Speicherbedarf zu reduzieren oder um Speicher temporär nur dann zu reservieren, wenn er wirklich benötigt wird.

Es existieren verschiedene Vorschläge zur Lösung dieses Problems, welche bisher alle auf der Verwendung von Zeigervariablen basieren. Der für die Felddaten benötigte Speicher wird mit BefehlsreferenzeintragALLOCATE/BefehlsreferenzeintragCALLOCATE/BefehlsreferenzeintragREALLOCATE reserviert und muss abschließend mit BefehlsreferenzeintragDEALLOCATE wieder freigegeben werden. Leider ist die Handhabung von Zeigervariablen nicht trivial und auch nicht Externer Link!treadsicher.

Die hier vorgestellte Lösung verwendet zur Speicherung der Felddaten eine einfache BefehlsreferenzeintragSTRING Variable. Diese kann auch in einem UDT in FreeBasic nach Bedarf dynamisch vergrößert oder verkleinert werden. Der resultierende Quelltext arbeitet keinesfalls langsam und funktioniert nicht nur unter LINUX, sondern auch unter Windows/DOS zuverlässig.

Für das variable Datenfeld wird eine TYPE Struktur mit dem benötigten BefehlsreferenzeintragDatentyp (SHORT, INTEGER, ...) erzeugt. Diese kann anschließend in dem (oder den) UDT(s) verwendet werden. Die TYPE Struktur wird automatisch durch ein BefehlsreferenzeintragMAKRO erzeugt. Hierzu dient der folgende Quelltext, der als "VarField.bi"-Datei abgespeichert wird und so in den eigenen Quelltext eingebunden wird:

' This is file VarField.bi, a type creator for dynamic arrays in UDTs
' (C) 2011 by Thomas[ dot ]Freiherr[ at ]gmx[ dot ]net
' License LGPL v 2.1.2
'
' * Use MAKE_VarField_(VariableType) to generate a new VarField-type
'   use MAKE_VarField_Named(Name, Type) when your type contains spaces
' * VarField datas have index 0 to max
'   (.dim_(9) makes 10 entries index 0 to 9)
' * VarField datas are stored in a STRING variable. The max STRING length
'   limits the number of elements.
' * The max string length is platform specific. In DOS it may be small
'   (the value VF_MAX should be reviewed -- I'm no DOS expert).
'
' Datei VarField.bi, generiert Datentyp fuer variable Felder in in UDTs
' (C) 2011 by Thomas[ dot ]Freiherr[ at ]gmx[ dot ]net
' Lizenz LGPL v 2.1
'
' * MAKE_VarField_(VariableType) generiert einen neuen VarField-Typ
'   MAKE_VarField_Named(Name, Type) verwenden, wenn Typ Leerzeichen enthaelt
' * VarField Daten haben einen Index von 0 bis max.
'   .dim_(9) erzeugt 10 Eintraege mit Index 0 bis 9
' * VarField Daten werden in einer STRING Variablen gespeichert. Die max.
'   Laenge eines STRING beschraenkt die Anzahl der Eintraege.
' * Die max STRING Laenge ist Plattform spezifisch. In DOS ist sie ggf.
'   klein. DOS-Anwender sollten den Wert VF_MAX pruefen/ggf. korrigieren.


' memory limits
#IFDEF __FB_DOS__
# DEFINE VF_MAX 2 ^ 16 - 1
#ELSE
# DEFINE VF_MAX 2147483647
#ENDIF
' some macros for convenience
#DEFINE VF_ERROR ? "VarField-error: Index out of range"
#MACRO VF_CHECK(S, VFSIZE)
  VAR l = (S + 1) * VFSIZE
  IF l > VF_MAX THEN ? "VarField-error: Out of memory -too much elements" : EXIT SUB
#ENDMACRO
'#DEFINE VF_CHECK(S, VFSIZE) '        alternative without error checking


' the convenient core macro here: create a new VarField of _typ_
#DEFINE MAKE_VarField_(_typ_) MAKE_VarField_Named_(_typ_, _typ_)

' if the _typ_ contains spaces (ie 'UDT PTR') you've to explicitly
' specify a _name_ without spaces by using this macro directly
#MACRO MAKE_VarField_Named_(_name_, _typ_)

TYPE VarField_##_name_
'           generate a new VarField (S = size[default 0], N = initializer)
  DECLARE CONSTRUCTOR(BYVAL S AS UINTEGER = 0, BYREF N AS STRING = "")
#IF TYPEOF(_typ_) = TYPEOF(STRING)
  DECLARE DESTRUCTOR()
#ENDIF
'                                                 GET the value at index I
  DECLARE PROPERTY v(BYVAL I AS UINTEGER) AS _typ_
'                                                   SET value N at index I
  DECLARE PROPERTY v(BYVAL I AS UINTEGER, BYREF N AS _typ_)
'        DIM a Varfield of size S with initializer N (old values get lost)
  DECLARE SUB dim_(BYVAL S AS UINTEGER = 0, BYREF N AS STRING = "")
' REDIM the Varfield to size S, preserve values, extend with initializer N
  DECLARE SUB redim_(BYVAL Az AS UINTEGER = 0, BYREF N AS STRING = "")
'                                    get the maximum index of the VarField
  DECLARE FUNCTION ubound_() AS UINTEGER
PRIVATE:
  AS UINTEGER Ma = 0
  AS STRING Va = STRING(SIZEOF(_typ_), 0)
END TYPE

CONSTRUCTOR VarField_##_name_##(BYVAL S AS UINTEGER = 0, BYREF N AS STRING = "")
  dim_(S, N)
END CONSTRUCTOR

#IF TYPEOF(_typ_) = TYPEOF(STRING)
DESTRUCTOR VarField_##_name_##()
  FOR i AS INTEGER = 0 TO Ma
    CAST(_typ_ PTR, SADD(Va))[i] = ""
  NEXT
END DESTRUCTOR
#ENDIF

PROPERTY VarField_##_name_##.v(BYVAL I AS UINTEGER) AS _typ_
  IF I <= Ma THEN RETURN CAST(_typ_ PTR, SADD(Va))[I]
  VF_ERROR : RETURN CAST(_typ_ PTR, SADD(Va))[0]
END PROPERTY

PROPERTY VarField_##_name_##.v(BYVAL I AS UINTEGER, BYREF N AS _typ_)
  IF I <= Ma THEN CAST(_typ_ PTR, SADD(Va))[I] = N : EXIT PROPERTY
  VF_ERROR
END PROPERTY

SUB VarField_##_name_##.dim_(BYVAL S AS UINTEGER = 0, BYREF N AS STRING = "")
  VF_CHECK(S, SIZEOF(_typ_))
  IF LEN(N) THEN
    Va = "" : WHILE LEN(Va) < l : Va &= N : WEND : Va = LEFT(Va, l)
  ELSE
    Va = STRING(l, 0)
  END IF
  Ma = S
END SUB

SUB VarField_##_name_##.redim_(BYVAL S AS UINTEGER = 0, BYREF N AS STRING = "")
  VF_CHECK(S, SIZEOF(_typ_))
  VAR la = LEN(Va)
  IF l > la THEN
    IF LEN(N) THEN
      WHILE LEN(Va) < l : Va &= N : WEND : Va = LEFT(Va, l)
    ELSE
      Va &= STRING(l - la, 0)
    END IF
  ELSE
#IF TYPEOF(_typ_) = TYPEOF(STRING)
    FOR i AS INTEGER = S + 1 TO Ma ' thanks to fxm
      CAST(_typ_ PTR, SADD(Va))[i] = ""
    NEXT
#ENDIF
    Va = LEFT(Va, l)
  END IF
  Ma = S
END SUB

FUNCTION VarField_##_name_##.ubound_() AS UINTEGER
  RETURN Ma
END FUNCTION

#ENDMACRO

Anwendung

Beispiel 1

Das folgende Beispiel verwendet verschiedene variable Datenfelder in einem UDT namens testtype

' Datei VarFieldTest.bas, ein Beispiel fuer dynamische Felder in UDTs
' (C) 2011 by Thomas[ dot ]Freiherr[ at ]gmx[ dot ]net
' Lizenz GPL v 3
'
' Dieses Beispiel zeigt den Einsatz variabler Felder in einem UDT

#INCLUDE ONCE "VarField.bi"

' create new VarField type SHORT
MAKE_VarField_(SHORT)

' create new VarField type INTEGER
MAKE_VarField_(INTEGER)

' create new VarField type UINTEGER
MAKE_VarField_(UINTEGER)

' create new VarField type STRING*26
MAKE_VarField_(STRING)


' an UDT with 3 variadic fields of different type
' ein UDT mit 3 verschiedenen dynamischen Feldern definieren
TYPE testtype
' the STRING type
' STRING benutzerdefiniert (siehe VarField.bi)
  AS VarField_STRING    a0 = 1 ' two entries with index 0 to 1

' a standard SHORT type
' ein FB Standardtyp SHORT
  AS VarField_SHORT    a1 '     one entry with index 0

' use either one of these (try both, watch negative numbers)
' eine der folgenden Zeile auskommentieren, beide probieren und
' negative Zahlen im vorletzten Ausgabeblock beobachten
  AS VarField_INTEGER  a2 = 7 '   8 entries with index 0 to 7
  'AS VarField_ULONGINT a2 = 7 '   8 entries with index 0 to 7
END TYPE
' and its DIM statement
' und Variable dimensionieren
DIM AS testtype test



' some demonstrating code here
' und hier Beispiele fuer den Zugriff auf die Eintraege
WITH test

' set the STRING entries, STRING Eintraege speichern
  .a0.v(0) = "abcdefghijklmnopqrstuvwxyz"
  .a0.v(1) = UCASE(.a0.v(0))

'?"show the strings:"
?"STRINGS anzeigen:"
  ?.a0.v(0)
  ?.a0.v(1)

' show the default value at default index
' zeigt den Vorgabewert mit Vorgabe-Index
? : ?"a1(0): ";.a1.v(0)

' shows error message
' zeigt Fehlermeldung (Index ausserhalb der Dimension)
? : ?"a1(99999): ";.a1.v(99999)

' redim the field a1
' Feld a1 dynamisch vergroessern
  .a1.redim_(99) ' 100 entries index 0 TO 99

'?"show all (empty) entries of a1:"
?"zeigt alle (leeren) Eintraege von a1:"
  FOR i AS INTEGER = 0 TO .a1.ubound_
    ?.a1.v(i),
  NEXT

' set the predimensioned 8 entries in a2
' fuellt die anfangs dimensionierten 8 Eintraege in a2
  FOR i AS INTEGER = 0 TO .a2.ubound_
    .a2.v(i) = 2 ^ i
  NEXT

'? : ?"show all (previously dimed and set) values in a2:"
? : ?"zeigt alle zuvor dimensionierten und befuellten Eintraege von a2:"
  FOR i AS INTEGER = 0 TO .a2.ubound_
    ?.a2.v(i),
  NEXT

' add new entries to a2 (leaves entries 0 to 7 unchanged)
' ergaenzt neue Eintraege fuer a2 (Eintraege 0 bis 7 bleiben erhalten)
  .a2.redim_(31) ' 32 entries with index 0 TO 31

' fill the new entries with their negative index
' fuellt die neuen Eintraege mit deren negativen Indizes
  FOR i AS INTEGER = 8 TO .a2.ubound_
    .a2.v(i) = -i
  NEXT

'? : ?"show all values in the redimensioned a2:"
? : ?"zeigt alle Werte des neudimensionierten a2:"
  FOR i AS INTEGER = 0 TO .a2.ubound_
    ?.a2.v(i),
  NEXT

' reduce the dimension of a2 (leaves entries 0 to 3 unchanged)
' reduziert die Feldgroesse (Eintraege 0 bis 3 bleiben erhalten)
  .a2.redim_(3) ' 4 entries with index 0 TO 3

'? : ?"show all values in the redimensioned a2:"
? : ?"zeigt alle Werte des zurueckdimensionierten a2:"
  FOR i AS INTEGER = 0 TO .a2.ubound_
    ?.a2.v(i),
  NEXT

END WITH

#IFNDEF __FB_UNIX__
SLEEP
#ENDIF

und erzeugt folgende Ausgabe

STRINGS anzeigen:
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ

a1(0):  0

a1(99999): VarField-error: Index out of range
 0
zeigt alle (leeren) Eintraege von a1:
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0
 0             0             0             0             0

zeigt alle zuvor dimensionierten und befuellten Eintraege von a2:
 1             2             4             8             16
 32            64            128          
zeigt alle Werte des neudimensionierten a2:
 1             2             4             8             16
 32            64            128          -8            -9
-10           -11           -12           -13           -14
-15           -16           -17           -18           -19
-20           -21           -22           -23           -24
-25           -26           -27           -28           -29
-30           -31          
zeigt alle Werte des zurueckdimensionierten a2:
 1             2             4             8  

Beispiel 2

Das Beispiel 2 verwendet ein variables Datenfeld VarField_SHORT im UDT namens UdtWithJaggedShort. Für diesen UDT wird ein weiteres variables Datenfeld namens VarField_UdtWithJaggedShort_PTR im UDT namens UdtWithJaggedUdt eingerichtet, wodurch eine flexible Baumstruktur mit variablen Datenfeldern auf zwei Ebenen entsteht:

' Datei VarFieldTest.bas, ein Beispiel fuer dynamische Felder in UDTs
' (C) 2011 by Thomas[ dot ]Freiherr[ at ]gmx[ dot ]net
' Lizenz GPL v 3
'
' Dieses Beispiel zeigt den Einsatz variabler Felder in einem UDT mit
' verschachtelter Struktur. VarField-Felder können auf beliebiger Ebene
' eingesetzt werden.

'#DEFINE English
#INCLUDE ONCE "VarField.bi"

' create new VarField type for SHORT
MAKE_VarField_(SHORT)

' create an UDT with VarField_SHORT
TYPE UdtWithJaggedShort
  AS INTEGER i
  AS VarField_SHORT s_jagg
END TYPE


' create new VarField type for UdtWithJaggedShort PTR
MAKE_VarField_Named_(UdtWithJaggedShort_Ptr, UdtWithJaggedShort PTR)


' create an UDT with VarField_InnerJaggedUDT_PTR
TYPE UdtWithJaggedUdt
  AS INTEGER i
  AS VarField_UdtWithJaggedShort_PTR jagg_UDT

  DECLARE CONSTRUCTOR( _
    BYVAL V AS INTEGER = 0, _
    BYVAL N AS UINTEGER = 0, _
    BYVAL Ni AS UINTEGER = 0)
  DECLARE DESTRUCTOR()
  DECLARE SUB set_Udt_No(BYVAL N AS UINTEGER, BYVAL Ni AS UINTEGER = 0)
END TYPE

'  V = value for INTEGER i
'  N = number of jagg_UDTs
' Ni = number of s_jagg elements in jagg_UDTs
CONSTRUCTOR UdtWithJaggedUdt( _
    BYVAL V AS INTEGER = 0, _
    BYVAL N AS UINTEGER = 0, _
    BYVAL Ni AS UINTEGER = 0)
  i = V
  set_Udt_No(N, Ni)
END CONSTRUCTOR

' since we created the UDTs with NEW, we've to free the memory when done
DESTRUCTOR UdtWithJaggedUdt()
  FOR i AS INTEGER = jagg_UDT.ubound_() TO 0 STEP -1
    IF jagg_UDT.v(i) THEN DELETE jagg_UDT.v(i)
  NEXT
END DESTRUCTOR

' method for setting the new number of jagg_UDTs (grow or shrink)
SUB UdtWithJaggedUdt.set_Udt_No(BYVAL N AS UINTEGER, BYVAL Ni AS UINTEGER = 0)
  VAR o = jagg_UDT.ubound_() : IF N = o THEN EXIT SUB
  IF o > N THEN
    ' before we shrink we've to free the jagg_UDTs memory (created by NEW)
    FOR i AS UINTEGER = o TO n + 1 STEP -1
      IF jagg_UDT.v(i) THEN DELETE jagg_UDT.v(i)
    NEXT
    ' release memory (preserve existing PTRs)
    jagg_UDT.redim_(n) ' never use dim_ because the PTRs get lost!
  ELSE
    ' get new memory for PTRs
    jagg_UDT.redim_(n) ' never use dim_ because the PTRs get lost!
    ' create InnerJaggedUDTs and dim i elements for s_jagg SHORTs
    FOR i AS INTEGER = o TO n
      IF jagg_UDT.v(i) THEN CONTINUE FOR
      jagg_UDT.v(i) = NEW UdtWithJaggedShort()
      IF Ni THEN jagg_UDT.v(i)->s_jagg.dim_(Ni)
    NEXT
  END IF
END SUB


' a convenience macro to show the result
#MACRO print_result(super,notify_de,notify_en)
?
#IFDEF English
 ?"The " & #super & " UDT has an INTEGER i = " & super.i & " and ";
 ?super.jagg_UDT.ubound_() + 1 & " UDT elements:"
 FOR i AS INTEGER = 0 TO super.jagg_UDT.ubound_()
   ?!"\t";
   ?"The jagg_UDT #" & i & " has one INTEGER i = " & super.jagg_UDT.v(i)->i;
   ?" and " & super.jagg_UDT.v(i)->s_jagg.ubound_() + 1 & " SHORT elements:"
   ?!"\t";
   FOR j AS INTEGER = 0 TO super.jagg_UDT.v(i)->s_jagg.ubound_()
     ?!"\t";super.jagg_UDT.v(i)->s_jagg.v(j);
   NEXT : ?
 NEXT : ? : ?notify_en
#ELSE
 ?"Der " & #super & " UDT hat ein INTEGER i = " & super.i & " und ";
 ?super.jagg_UDT.ubound_() + 1 & " UDT Elemente:"
 FOR i AS INTEGER = 0 TO super.jagg_UDT.ubound_()
   ?!"\t";
   ?"Der jagg_UDT #" & i & " hat einen INTEGER i = " & super.jagg_UDT.v(i)->i;
   ?" und " & super.jagg_UDT.v(i)->s_jagg.ubound_() + 1 & " SHORT Elemente:"
   ?!"\t";
   FOR j AS INTEGER = 0 TO super.jagg_UDT.v(i)->s_jagg.ubound_()
     ?!"\t";super.jagg_UDT.v(i)->s_jagg.v(j);
   NEXT : ?
 NEXT : ? : ?notify_de
#ENDIF
SLEEP : WHILE LEN(INKEY) : WEND
#ENDMACRO


' ****************
' ***** main *****
' ****************
#IFNDEF English
?"Eine leere Struktur mit zwei jagg_UDT Elementen"
#ELSE
?"An empty structure with two jagg_UDT elements"
#ENDIF

DIM AS UdtWithJaggedUdt super = UdtWithJaggedUdt(0, 1, 0)

print_result(super,!"Nach Tastendruck werden:\n die jagg_UDTs-Anzahl erhoeht, sowie\n neue s_jagg Felder dimensioniert und Werte zugewiesen",_
                   "Press a key for adding jagg_UDTs with included s_jagg SHORTs")

super.set_Udt_No(6) ' 7 jagg_UDTs (0 TO 6)

FOR i AS INTEGER = 0 TO super.jagg_UDT.ubound_() '                alle jagg_UDTs
  super.jagg_UDT.v(i)->s_jagg.dim_(i) ' s_JAGG SHORTs im jagg_UDT dimensionieren

  FOR j AS INTEGER = 0 TO i
    super.jagg_UDT.v(i)->s_jagg.v(j) = 10 * i + j '           und Werte zuweisen
  NEXT
NEXT

print_result(super,!"Nach Tastendruck wird die Dimension der s_jagg Felder veraendert\n(neue Werte = -999, ueberzaehlige alte gehen verloren)",_
                   "Press a key for changing the s_jagg SHORTs dimension (new values = -999)")

FOR i AS INTEGER = 0 TO super.jagg_UDT.ubound_() '                alle jagg_UDTs
  VAR new_dim = super.jagg_UDT.ubound_() - i
  super.jagg_UDT.v(i)->s_jagg.redim_(new_dim, MKSHORT(-999)) ' s_jagg neu dimensionieren
NEXT

print_result(super,!"Nach Tastendruck werden 4 weitere jagg_UDTs hinzugefuegt (i-Wert initialisiert)",_
                   "Press a key for adding 4 more jagg_UDTs with init-i-value")

' you can increase the number of jagg_UDTs by redim_ (never user dim_ for UDT PTRs)
VAR old_num = super.jagg_UDT.ubound_(), new_add = 4
super.set_Udt_No(old_num + new_add)

' set value in new UDTs
FOR i AS INTEGER = 1 TO new_add '                         alle neuen Elemente
  super.jagg_UDT.v(old_num + i)->i = 1111 * i ' i-Werte zuweisen im super UDT
NEXT

print_result(super,"Nach Tastendruck wird die Anzahl der jagg_UDTs auf 5 reduziert",_
                   "Press a key for shrinking the number of jagg_UDTs to 5 elements")

super.set_Udt_No(4) ' Anzahl der jagg_UDT neu zuweisen (Verkleinern)

print_result(super,"Fertig","Done")

#IFNDEF __FB_UNIX__
SLEEP
#ENDIF

Beispiel2 erzeugt folgende Ausgabe

Eine leere Struktur
Der super UDT hat ein INTEGER i = 0 und 2 UDT Elemente:
    Der jagg_UDT #0 hat einen INTEGER i = 0 und 1 SHORT Elemente:
         0
    Der jagg_UDT #1 hat einen INTEGER i = 0 und 1 SHORT Elemente:
         0

Nach Tastendruck werden:
 die jagg_UDTs-Anzahl erhoeht, sowie
 neue s_jagg Felder demensioniert und Werte zugewiesen

Der super UDT hat ein INTEGER i = 0 und 7 UDT Elemente:
    Der jagg_UDT #0 hat einen INTEGER i = 0 und 1 SHORT Elemente:
         0
    Der jagg_UDT #1 hat einen INTEGER i = 0 und 2 SHORT Elemente:
         10  11
    Der jagg_UDT #2 hat einen INTEGER i = 0 und 3 SHORT Elemente:
         20  21  22
    Der jagg_UDT #3 hat einen INTEGER i = 0 und 4 SHORT Elemente:
         30  31  32  33
    Der jagg_UDT #4 hat einen INTEGER i = 0 und 5 SHORT Elemente:
         40  41  42  43  44
    Der jagg_UDT #5 hat einen INTEGER i = 0 und 6 SHORT Elemente:
         50  51  52  53  54  55
    Der jagg_UDT #6 hat einen INTEGER i = 0 und 7 SHORT Elemente:
         60  61  62  63  64  65  66

Nach Tastendruck wird die Dimension der s_jagg Felder veraendert
(neue Werte = -999, ueberzaehlige alte gehen verloren)

Der super UDT hat ein INTEGER i = 0 und 7 UDT Elemente:
    Der jagg_UDT #0 hat einen INTEGER i = 0 und 7 SHORT Elemente:
         0  -999    -999    -999    -999    -999    -999
    Der jagg_UDT #1 hat einen INTEGER i = 0 und 6 SHORT Elemente:
         10  11 -999    -999    -999    -999
    Der jagg_UDT #2 hat einen INTEGER i = 0 und 5 SHORT Elemente:
         20  21  22 -999    -999
    Der jagg_UDT #3 hat einen INTEGER i = 0 und 4 SHORT Elemente:
         30  31  32  33
    Der jagg_UDT #4 hat einen INTEGER i = 0 und 3 SHORT Elemente:
         40  41  42
    Der jagg_UDT #5 hat einen INTEGER i = 0 und 2 SHORT Elemente:
         50  51
    Der jagg_UDT #6 hat einen INTEGER i = 0 und 1 SHORT Elemente:
         60

Nach Tastendruck werden 4 weitere jagg_UDTs hinzugefuegt (i-Wert initialisiert)

Der super UDT hat ein INTEGER i = 0 und 11 UDT Elemente:
    Der jagg_UDT #0 hat einen INTEGER i = 0 und 7 SHORT Elemente:
         0  -999    -999    -999    -999    -999    -999
    Der jagg_UDT #1 hat einen INTEGER i = 0 und 6 SHORT Elemente:
         10  11 -999    -999    -999    -999
    Der jagg_UDT #2 hat einen INTEGER i = 0 und 5 SHORT Elemente:
         20  21  22 -999    -999
    Der jagg_UDT #3 hat einen INTEGER i = 0 und 4 SHORT Elemente:
         30  31  32  33
    Der jagg_UDT #4 hat einen INTEGER i = 0 und 3 SHORT Elemente:
         40  41  42
    Der jagg_UDT #5 hat einen INTEGER i = 0 und 2 SHORT Elemente:
         50  51
    Der jagg_UDT #6 hat einen INTEGER i = 0 und 1 SHORT Elemente:
         60
    Der jagg_UDT #7 hat einen INTEGER i = 1111 und 1 SHORT Elemente:
         0
    Der jagg_UDT #8 hat einen INTEGER i = 2222 und 1 SHORT Elemente:
         0
    Der jagg_UDT #9 hat einen INTEGER i = 3333 und 1 SHORT Elemente:
         0
    Der jagg_UDT #10 hat einen INTEGER i = 4444 und 1 SHORT Elemente:
         0

Nach Tastendruck wird die Anzahl der jagg_UDTs auf 5 reduziert

Der super UDT hat ein INTEGER i = 0 und 5 UDT Elemente:
    Der jagg_UDT #0 hat einen INTEGER i = 0 und 7 SHORT Elemente:
         0  -999    -999    -999    -999    -999    -999
    Der jagg_UDT #1 hat einen INTEGER i = 0 und 6 SHORT Elemente:
         10  11 -999    -999    -999    -999
    Der jagg_UDT #2 hat einen INTEGER i = 0 und 5 SHORT Elemente:
         20  21  22 -999    -999
    Der jagg_UDT #3 hat einen INTEGER i = 0 und 4 SHORT Elemente:
         30  31  32  33
    Der jagg_UDT #4 hat einen INTEGER i = 0 und 3 SHORT Elemente:
         40  41  42

Fertig

Abschlussbemerkungen

Viel Erfolg bei der Anwendung!

English

See Externer Link!english forum.


Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 24.04.2011 von MitgliedTJF angelegt.
  • Die aktuellste Version wurde am 29.06.2013 von MitgliedTJF gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen