Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dynamisches Array erzeugen (https://www.delphipraxis.net/2383-dynamisches-array-erzeugen.html)

Snoop007 20. Jan 2003 22:47


Dynamisches Array erzeugen
 
Hi,
ist es möglich ein Dynamisches Array während der laufzeit zu erzeugen ?

z.b. x : array of array of array of array ..... : string

Hansa 20. Jan 2003 22:49

Hi,

so einfach gehts nicht. Was für ein Typ soll das sein ?

Gruß
Hansa

Snoop007 20. Jan 2003 22:53

string :)

Hansa 20. Jan 2003 23:07

Hi,

als erstes wären Pointer zu benutzen. Dann kannst Du machen, was Du willst.

Was Deine Frage aber wahrscheinlich genauer trifft (array of array usw.) :

Code:
To declare multidimensional dynamic arrays, use iterated array of ... constructions. For example,

type TMessageGrid = array of array of string;

var Msgs: TMessageGrid;

declares a two-dimensional array of strings. To instantiate this array, call SetLength with two integer arguments. For example, if I and J are integer-valued variables,

SetLength(Msgs,I,J);

allocates an I-by-J array, and Msgs[0,0] denotes an element of that array.
You can create multidimensional dynamic arrays that are not rectangular. The first step is to call SetLength, passing it parameters for the first n dimensions of the array. For example,

var Ints: array of array of Integer;

SetLength(Ints,10);

allocates ten rows for Ints but no columns. Later, you can allocate the columns one at a time (giving them different lengths); for example

SetLength(Ints[2], 5);

makes the third column of Ints five integers long. At this point (even if the other columns haven’t been allocated) you can assign values to the third column—for example, Ints[2,4] := 6.
The following example uses dynamic arrays (and the IntToStr function declared in the SysUtils unit) to create a triangular matrix of strings.

var

  A : array of array of string;
  I, J : Integer;
begin
  SetLength(A, 10);
  for I := Low(A) to High(A) do
  begin
    SetLength(A[I], I);
    for J := Low(A[I]) to High(A[I]) do
      A[I,J] := IntToStr(I) + ',' + IntToStr(J) + ' ';
  end;
end;
Findest Du dazu eine Hilfe in der deutschen Version, so sag mir es bitte, bin nämlich jetzt zu faul, das zu übersetzen.

Gruß
Hansa

P.S.: Lese gerade, da werden auch Pointer benutzt, gehen tut es also anscheinend, wie ich anfangs vermutet habe.

Hansa 20. Jan 2003 23:21

Hi,

das hier habe ich gemeint (falscher Beitrag gepostet), ohne Englisch wärs natürlich jetzt schlecht :

Zitat:

Dynamic arrays do not have a fixed size or length. Instead, memory for a dynamic array is reallocated when you assign a value to the array or pass it to the SetLength procedure. Dynamic-array types are denoted by constructions of the form

array of baseType

For example,

var MyFlexibleArray: array of Real;

declares a one-dimensional dynamic array of reals. The declaration does not allocate memory for MyFlexibleArray. To create the array in memory, call SetLength. For example, given the declaration above,

SetLength(MyFlexibleArray, 20);

allocates an array of 20 reals, indexed 0 to 19. Dynamic arrays are always integer-indexed, always starting from 0.
Dynamic-array variables are implicitly pointers and are managed by the same reference-counting technique used for long strings. To deallocate a dynamic array, assign nil to a variable that references the array or pass the variable to Finalize; either of these methods disposes of the array, provided there are no other references to it. Dynamic arrays of length 0 have the value nil. Do not apply the dereference operator (^) to a dynamic-array variable or pass it to the New or Dispose procedure.

If X and Y are variables of the same dynamic-array type, X := Y points X to the same array as Y. (There is no need to allocate memory for X before performing this operation.) Unlike strings and static arrays, dynamic arrays are not automatically copied before they are written to. For example, after this code executes—

var

A, B: array of Integer;
begin
SetLength(A, 1);
A[0] := 1;
B := A;
B[0] := 2;
end;

—the value of A[0] is 2. (If A and B were static arrays, A[0] would still be 1.)
Assigning to a dynamic-array index (for example, MyFlexibleArray[2] := 7) does not reallocate the array. Out-of-range indexes are not reported at compile time.
When dynamic-array variables are compared, their references are compared, not their array values. Thus, after execution of the code

var

A, B: array of Integer;
begin
SetLength(A, 1);
SetLength(B, 1);
A[0] := 2;
B[0] := 2;
end;

A = B returns False but A[0] = B[0] returns True.
To truncate a dynamic array, pass it to SetLength or Copy and assign the result back to the array variable. (The SetLength procedure is usually faster.) For example, if A is a dynamic array, A := SetLength(A, 0, 20) truncates all but the first 20 elements of A.
Once a dynamic array has been allocated, you can pass it to the standard functions Length, High, and Low. Length returns the number of elements in the array, High returns the array’s highest index (that is, Length – 1), and Low returns 0. In the case of a zero-length array, High returns –1 (with the anomalous consequence that High < Low).

Note: In some function and procedure declarations, array parameters are represented as array of baseType, without any index types specified. For example,

function CheckStrings(A: array of string): Boolean;

This indicates that the function operates on all arrays of the specified base type, regardless of their size, how they are indexed, or whether they are allocated statically or dynamically. See Open array parameters.
Multidimensional dynamic arrays
Aber eine Frage : wozu brauchst Du das ? Das geht bestimmt einfacher. Sieht nach C aus.

Gruß
Hansa

Snoop007 21. Jan 2003 10:29

hi,
ich habe beide beiträge gerade überflogen, der letzte beschreib aber nur ein eindemensionales array

ich lese eine baumstrucktur ein, vergleichbar mit xml, da ich nicht weiss wieviele "blätter" ein "ast" hast brauche ich ein mehrfach dynamisches array.
es sollten auf die "blätter" mit einem index zugegriffen werden

Jan 21. Jan 2003 10:53

Zitat:

Zitat von Snoop007
hi,
ich habe beide beiträge gerade überflogen, der letzte beschreib aber nur ein eindemensionales array

Hallo Snoop007,
Der letzte Artikel beschriebt einfach nur das Verhalten eines dynamischen arrays anhand eines 1-Dimensionalen arrays, was nicht heißt, dass das nicht auch genauso mit mehrdimensionalen arrays funktioniert.
Gruß
Jan

Hansa 21. Jan 2003 10:54

Uff,

Zitat:

Zitat von Snoop007
ich lese eine baumstrucktur ein, vergleichbar mit xml, da ich nicht weiss wieviele "blätter" ein "ast" hat brauche ich ein mehrfach dynamisches array.

das da hört sich aber böse, sehr böse :shock: nach komplizierten Zeiger-Strukturen an und nicht bloß eine einfach verkettete Liste. Bei sowas ist mir schon mal bald schlecht geworden und das 4 Wochen lang. :mrgreen: Und darauf willst Du noch über einen Index zugreifen ? brrrrrrrrrrr :corky: Habe den Text auch nur überflogen, aber wenn da schon nur was eindimensionales beschrieben wird, oh je. Mit den Pointern das hab ich ja schon gesehen. Willst Du so was wie eine mehrdimensionale Baumstruktur stricken, dann stricke Dir gleich einen warmen Pullover dazu. Ich lasse mich aber gerne eines besseren belehren und werde das hier mal verfolgen. *grusel*

Gruß
Hansa

Jan 21. Jan 2003 11:00

Hallo Hansa,
was jagt dir denn da so einen großen Schrecken ein?
Ich würde das über einen rekursiven Algorythmus lösen, ähnlich dem des Dateistruktur Auslesens und dann dementsprechend im rekursiven Algorythmus den dynamischen Array erweitern. Klingt doch garnicht so schwer....
Für Belehrungen bin ich natürlich immer dankbar!
Gruß
Jan

Hansa 21. Jan 2003 11:24

Hi,

für mich ist das da im Moment ein Gruselkabinett. :spin: Zeiger kann ich schon nicht sehen. Was noch schlimmer ist : rekursive Prozeduren und dann noch zusammen mit Zeigern. Aber Du hast schon Recht wenn so etwas in der Art und Weise aufgebaut werden muß, dann wirklich schon rekursiv. Mit dynamischen Arrays habe ich mich noch nicht so beschäftigt, aber ist es nicht so, daß diese nur in sofern dynamisch sind, daß die Größe erst zur Laufzeit festgelegt wird ? Dies würde aber bedeuten, daß Du eine Maximallänge z.B. von 20 festlegst und eine Exception kriegst falls es doch 21 Elemente sind. Bei einem mehrdimensionalen Baum glaube ich, ist es sehr wahrscheinlich, daß der sehr unausgeglichen ist. Hast Du nun aber einen Baum mit 4 Ästen von jeweils 2,10,15 und 200 Blättern, mußt Du für jeden Ast 200 Blätter vorsehen ! Da stehts ja sogar :

Zitat:

Zitat von Borland
Dynamic-array variables are implicitly pointers

Dyn. Arrays sind Pointer, die schon mal indiziert sind und deshalb einfacher zu handhaben sind. Ist die Maximalanzahl der Blätter eines Astes nicht von vorne herein klar, kommst Du an Pointern nicht vorbei. Für ein ähnliches Problem vor längerer Zeit bin ich jedenfalls nicht an Zeigerstrukturen rumgekommen. Ich bin mir fast sicher, daß diese Tatsache einer der wenigen Punkte ist, bei denen C++ Pascal / Delphi weit überlegen ist. Warum ist Unix wohl in C geschrieben?

Gruß
Hansa

Chewie 21. Jan 2003 12:58

Hm, seltsam, ich dachte, es wäre umgekehrt. Zugegeben, ich kenne C++ nur sehr oberflächlich und hab noch nie Code darin geschrieben, aber soweit ich weiß, sind dyn. Arrays in C++ nur insoweit dynamisch, als dass zur Laufzeit die Größe bei der Instantiierung beliebig festgelegt werden kann. Danach ist Schluss. Hier könnt ihr micg aber gerne eines Besseren belehren, da ich wie gesgt, noch kaum Umgamg mit C++ hatte.
Bei ObjektPascal sieht das aber anders aus. Da gibt es eine schöne Funktion namens SetLength, die nicht nur für Strings, sondern auch für dyn. Arrays gillt. Und man kann sie nicht nur beim Erstellen des Arrays aufrufen, sondern so oft wie man will. Und das Tollste ist, dass die Daten im Array innerhalb der neuen Größe erhalten bleiben. Also entweder sprecht ihr von einer anderen Sprache oder ich träumte die letzten zwei, drei Jahre einen langen, schönen Traum... :freak:

X-Dragon 21. Jan 2003 15:17

Hier hab ich was zu Array gefunden (mehrdimensional, dynamisch,...), vielleicht hilft das ja weiter:
http://home.t-online.de/home/PeterJH...les/arrays.htm

Beschränkte Arrays haben mir bisher immer gereicht, deshalb warte ich mal ab wie sich das hier so entwickelt :) .

oki 21. Jan 2003 16:17

Hallo,

das hört sich ja interessant an.

Baumstrukturen und deren dynamische Verwaltung bearbeite ich immer mittels TTreeNode-Objekten.

Ehrlich habe ich die noch nicht ohne TTreeView verwendet, aber ich glaube der muß nicht unbedingt sein.
Der Vorteil ist, dass einige nützliche Methoden für die "Zweige" mitgeliefert werden wie "GetNext", GetFirstChild" etc.

Die Eigenschaft TTreeNode.Data kann man gut für Zeiger auf eigene Records verwenden.

Jetzt bitte nicht schimpfen, ich nenne es Iteration, aber von mir aus können wir es auch Recursion nennen (ich meine Methode ruft sich selbst auf) ist der beste Ansatzt um einen Baum zur Laufzeit mit x-beliebigen Ästen abzuarbeiten. Ich mach es jedenfalls immer so.

Gruß Oki

lodda 21. Jan 2003 16:40

Hallo

@oki: Nur mal so nebenbei: Soweit ich weiß spricht man von Iteration, wenn man mit Schleifen arbeitet, die irgendeinen Wert hoch- bzw. runterzählen.
Von Rekursion spricht man wenn sich eine Methode selbst aufruft oder so ähnlich.

Jetzt noch eine Frage an alle: Muss der Speicher der mit SetLength reserviert wurde auch von Hand wieder freigeben werden, oder erledigt das Delphi automatisch?

oki 21. Jan 2003 16:50

Hallo Lodda,

ja ja, ich hab ja schon gesagt dass ich das nicht so piniebel sehe. Du hast sicher Recht. Mir ist ja wichtiger dass ich jemandem helfen kann.

Mit SetLength belegten Speicher kannst du automatisch mit der Zuweisung von nil auf die Variable (dyn Array) frei geben. Das Drumherum macht Delphi.
Weist du der Variablen eine neue Länge zu (zweites mal SetLength) brauchst du dich nicht um den Speicher zu kümmern. Macht alles Delphi. Also ganz easy.

Gruß Oki

lodda 21. Jan 2003 16:58

Warum wird der Speicher freigeben, wenn ich der Variable nil zuweise :?: :?: :?: Ich dachte eine Variable darf den Wert nil besitzen.

Snoop007 21. Jan 2003 19:17

ich glaube das mein anliegen etwas falsch verstanden wurde
ich weiss wie ich mit dynmischen array's arbeite, diese sind mir auch lieber als statische

mein problem bei der sache ist nur, es wird ja von vornherein festgelegt was für ein array man haben möchte
ein eindemensionales x array of string ein zweidemensionales x array of array of integer usw. ...

bei mir sollte es aber ein n demensionales array sein
genau das was oki angesprochen hat, an TreeNodes habe ich nicht gedacht
ich glaube das hilft mir ungemein :)

danke allen die hier gepostet haben :)

oki 22. Jan 2003 08:52

Hallo Snoop 007,

schön, dass dir meine Idee was gebracht hat. Da ich selber gerade an TreeNodes rumprogrammiere kannst du dich gene weiter direkt an mich wenden wenn du da auf Probleme stößt. So ich kann helf ich gerne.

Für lodda,

schau einfach mal in der Delphi Hilfe unter dem Index dynamische Arrays nach. Da steht alles drin. Es ist wirklich so wie ich sagte.

Gruß Oki


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz