Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie ermittelt man die Grenzen mehrdimensionaler Arrays? (https://www.delphipraxis.net/133722-wie-ermittelt-man-die-grenzen-mehrdimensionaler-arrays.html)

Popov 7. Mai 2009 14:40


Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Mit Low und High kann man die Grenzen von Arrys ermitteln. Beim Code

Delphi-Quellcode:
var
  a: array[1..100] of Byte;
  i: Integer;
begin
  i := High(a);
erhalte ich bei i 100 als obere Grenze. Soweit alles klar. Nur wie, bzw. überhaupt, kriegt man bei mehrdimensionaler Arrays die Info für die weitere Dimension?

Delphi-Quellcode:
var
  a: array[1..100, 10..10000] of Byte;
  i: Integer;
begin
  i := High(a);
Hier erhalte ich nur den oberen Wert der ersten Dimension, also 100, ich brauche aber den zweiten Wert.

Bernhard Geyer 7. Mai 2009 14:41

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Wie wäre es damit?
Delphi-Quellcode:
  j := High(a[0]);

Popov 7. Mai 2009 14:55

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Also High(a[0]) funktioniert bei mir nicht (D3 und D7), aber High(a[1]) gibt die Grenze der zweiten Dimension. Allerdings gibt auch High(a[20]) die Grenze der zweiten Dimension.

Gibt es da eine Logik oder funktioniert es zufällig? Denn

Delphi-Quellcode:
var
  a: array[1..100, 10..10000, 0..10] of Byte;
  i: Integer;
begin
  i := High(a[2]);
gibt nicht die dritte Dimension zurück, sondern immer noch der zweiten.

himitsu 7. Mai 2009 15:02

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
vielleicht fällt es so besser auf:
Delphi-Quellcode:
i := High(a[Low(a)]); // Obergrenze des Unterarray vom 1. Array der obersten Ebene
i := Low(a[Low(a)]); // Untergrenze des Unterarray vom 1. Array der obersten Ebene
Delphi-Quellcode:
var a: array[1..100, 10..10000] of Byte;
i := High(a[Low(a)]);
i := High(a[1]);   // oder direkt
i := High(a[99]);  // 1..100 ... was ist egal, da alle Unterarrays gleich groß sind

var a: array[1..100, 10..10000, 0..10] of Byte;
i := High(a[Low(a), Low(a[Low(a)])]);
i := High(a[Low(a)][Low(a[Low(a)])]);
i := High(a[1][10]);    // oder direkt
i := High(a[1, 10]);
i := High(a[99][9999]); // 1..100 > 10..10000 ... was ist hier ebenfalls egal
i := High(a[99, 9999]);

Hawkeye219 7. Mai 2009 15:04

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Hallo,

vielleicht wird es auch klarer, wenn man die Array-Deklaration so schreibt:

Delphi-Quellcode:
var
  a: array [1..100] of array [10..10000] of array [0..10] of Byte;
Gruß Hawkeye

DeddyH 7. Mai 2009 15:06

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  a: array[1..100, 10..10000, 0..10] of Byte;
begin
  ShowMessage(Format('[%d..%d,%d..%d,%d..%d]',[Low(a),
                                               High(a),
                                               Low(a[Low(a)]),
                                               High(a[Low(a)]),
                                               Low(a[Low(a),Low(a[Low(a)])]),
                                               High(a[Low(a),Low(a[Low(a)])])]));
end;
Je mehr Dimensionen, desto komplizierter. Aber vielleicht hab ich auch nur ein Brett vor dem Kopf und es geht auch einfacher.

[edit] :oops: in der Art hatte das himitsu ja bereits gepostet [/edit]

taaktaak 7. Mai 2009 15:08

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Oder anders ausgedrückt:
Es wird immer die Obergrenze des nächstfolgenden Sub-Arrays ermittelt.

Delphi-Quellcode:
var a : Array [1..10,1..100,1..1000] of integer;

procedure TfoTest19.FormShow(Sender:TObject);
begin
  listbox1.Items.add(inttostr(high(a)    ));
  listbox1.Items.add(inttostr(high(a[1]) ));
  listbox1.Items.add(inttostr(high(a[1,1])));
end;

Popov 7. Mai 2009 15:22

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Ok, alles klar, hab es jetzt verstanden.

Danke an alle :thumb:

mr_emre_d 7. Mai 2009 16:02

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Eine brutale Möglichkeit, die Größe(n) eines dynamisch mehrdimensionalen Arrays zu messen, wäre folgender:

Delphi-Quellcode:
function CntArrDimensions( const Arr: Pointer ): String;
begin
  try
    Result := '0..' + IntToStr( pCardinal( Cardinal(Arr^) - 4 )^ - 1 ) + ' ' + CntArrDimensions( Pointer( Cardinal(Arr^) ) );
  except
  end;
end;

// Testaufruf
var
  Test: Array of Array of Array of Byte;
begin
  SetLength( Test, 10, 20, 30 );
  ShowMessage( CntArrDimensions( @Test ) );
MfG

Mithrandir 7. Mai 2009 16:05

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Ay Caramba.. :shock:

Aber was soll denn der überflüssige Try..Except - Block da drin? :gruebel:

quendolineDD 7. Mai 2009 16:09

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Eine Exception verschlucken, damit sie nicht geworfen wird.

Mithrandir 7. Mai 2009 16:13

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Das war mir klar. Aber imho ist das kein guter Programmierstil. Entweder ganz, oder gar nicht.

mr_emre_d 7. Mai 2009 16:18

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Ja stimmt - deshalb ja auch >>brutal<< ;)

Mir fällt leider keine Funktion ein, mit der man die Protektion eines Bereiches im Speicher auslesen kann ..

Ich hab mal den Try-Except Block weggetan und es mit VirtualProect - auch keine gute Lösung - gelöst :D

Delphi-Quellcode:
function CntArrDimensions( const Arr: Pointer ): String;
var
  Protection: Cardinal;
begin
  VirtualProtect( pCardinal( Cardinal(Arr^) - 4 ), 4, PAGE_READWRITE, Protection );
  VirtualProtect( pCardinal( Cardinal(Arr^) - 4 ), 4, Protection, Protection );
  if Protection = 0 then
    Exit;
  Result := '0..' + IntToStr( pCardinal( Cardinal(Arr^) - 4 )^ - 1 ) + ' ' + CntArrDimensions( Pointer( Cardinal(Arr^) ) );
end;
Edit:
@Daniel - Kuhle Signatur ;)

himitsu 7. Mai 2009 16:19

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Delphi-Quellcode:
function CntArrDimensions(Arr: Pointer): String;
begin
  if Arr = nil then Result := 'leer'
  else Result := '0..' + IntToStr((PPInteger(Arr)^ - 4)^ - 1));
end;
für mehr Ebenen mußt du über die RTTI gehn, denn anders ist keine sichere Auswertung möglich, da du nicht weißt was im Array für Daten enthalten und ob das überhaupt Arrays-Zeiger sind.

Mit viel Spaß könnte ich über ein einfaches Array of Integer deinen Code in eine Endlosschleife steuern :nerd:
z.B.:
Delphi-Quellcode:
Var Arr: Array of Integer;
SetLength(Arr, 1);
Arr[0] := Integer(Arr);

Mithrandir 7. Mai 2009 16:21

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Zitat:

Zitat von mr_emre_d
Edit:
@Daniel - Kuhle Signatur ;)

Danke. ;) Mir gefällt der Spruch einfach. :)

himitsu 7. Mai 2009 16:34

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Was mir noch aufgefallen ist, dein Code liefert immer nur die Größe des ersten Arrays einer Ebene und womöglich noch anderes, wenn es an der tiefsten Ebene vorbei ist.

Ein dynamisches Array kann aber für jedes Element/Unterarray einer Ebene 'ne andere Größe besitzen.

mr_emre_d 7. Mai 2009 16:37

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
So ist es :) Jedoch ist sie leicht änderbar :P Und wenn man alle Unterarrays nach ihrer Größe abfragt, dann hat man m^n Abfragen und es wird ganz bestimmt nen Stack-Overflow geben :P

MfG

himitsu 7. Mai 2009 16:40

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
es gibt da zwar 'ne unbestimmte anzahl an Arrays, aber denoch nur soviele Funktionsaufrufe maximal gleichzeitig, wie es Ebenen gibt :angel2:

Schau dir (wenn es dir möglich ist) mal in der SystemUnit die Funktionen _Finalize, _FinalizeArray und _FinalizeRecord an :stupid:

Popov 7. Mai 2009 17:13

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Zitat:

Zitat von Bernhard Geyer
Wie wäre es damit?
Delphi-Quellcode:
  j := High(a[0]);

Ich hab mir dein Hinweis noch mal angesehen. Es scheint doch richtig zu sein, nur nicht bei meinem Beispiel, da er ja [1..100] dimensioniert war und 0 außerhalb der unteren Grenzen war. So hätte es funktioniert

Delphi-Quellcode:
var
  a: array[[0..100, 10..10000] of Byte;
  i: Integer;
begin
  i := High(a);

DeddyH 7. Mai 2009 17:18

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
High(a) liefert dann 100, High(a[0]) 10000.

Popov 7. Mai 2009 17:43

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Ja, aber nur weil die erste Dimension [0..100, 10..10000] bei 0 anfängt. Würde sie bei 5 anfangen, also [5..100, 10..10000] würde 0 einen Fehler ausgeben, erst High(a[5]) würde 10000 zurück geben. Der Wert in der eckigen Klammer muß innerhalb der Grenzen der ersten Dimension liegen. Das habe ich bei ersten Antwort noch nicht verstanden.

oki 7. Mai 2009 17:51

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Zitat:

Zitat von Popov
Ja, aber nur weil die erste Dimension [0..100, 10..10000] bei 0 anfängt. Würde sie bei 5 anfangen, also [5..100, 10..10000] würde 0 einen Fehler ausgeben, erst High(a[5]) würde 10000 zurück geben. Der Wert in der eckigen Klammer muß innerhalb der Grenzen der ersten Dimension liegen. Das habe ich bei ersten Antwort noch nicht verstanden.

und genau aus diesem Grund kam von mehreren Leuten dieser Hinweis:
(als erstes von Himitsu)
Delphi-Quellcode:
i := High(a[Low(a)]); // Obergrenze des Unterarray vom 1. Array der obersten Ebene
i := Low(a[Low(a)]); // Untergrenze des Unterarray vom 1. Array der obersten Ebene
Durch das Low bist du ja nicht auf die direkte Angabe des nidriegsten Wertes angewiesen, sondern läßt sie ermitteln. High tut das Gleiche wie bei DeddyH zu sehen.

Gruß oki

DeddyH 7. Mai 2009 17:52

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Deshalb ja auch meine Verrenkungen mit High(a[Low(a)]) usw.

[edit] oki war schneller und ausführlicher. *g* [/edit]

Popov 7. Mai 2009 17:58

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Das ist mir schon klar, aber zuerst muß man ja verstehen warum es so ist. Warum steht da Low in High(a[Low(a)]). Zuerst muß der Groschen fallen.

DeddyH 7. Mai 2009 18:08

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Die innere Klammer steht für die erste Dimension.

Popov 7. Mai 2009 19:17

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Und was ist das a in der Klammer?

DeddyH 7. Mai 2009 19:24

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Das Array, was denn sonst?

Popov 7. Mai 2009 19:26

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Aha.

Edit:

Ok, jetzt verstehe ich was DeddyH will. Ich dachte er will mich etwas ärgern, aber er bezieht sich wohl auf den Beitrag mit dem Groschen. Sorry DeddyH, der Groschen ist bereits gefallen. Ich bezog meinen Satz mit dem Groschen rückwirkend auf Bernhard Geyers erste Antwort. Da ist bei mir der Groschen noch nicht gefallen. Inzwischen schon. Ich gebe aber zu, daß der Satz so kling also ob ich es noch nicht verstanden habe.

Ok DeddyH, mein Fehler, sorry, wollte dich nicht ärgern. :wink:

DeddyH 7. Mai 2009 19:30

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Denken wir mal etwas anders.
Delphi-Quellcode:
var a: array[1..10] of array[3..7] of irgendwas;
//andere Schreibweise
var a: array[1..10,3..7] of irgendwas;

//Letztes Element der 1. Dimension
bla := High(a);

//Letztes Element (2. Dimension) des ersten Elementes (1. Dimension)
bla := High(a[Low(a)]);
Etc. pp.

Popov 7. Mai 2009 19:32

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Nochmal sorry:

Zitat:

Zitat von Popov
Edit:

Ok, jetzt verstehe ich was DeddyH will. Ich dachte er will mich etwas ärgern, aber er bezieht sich wohl auf den Beitrag mit dem Groschen. Sorry DeddyH, der Groschen ist bereits gefallen. Ich bezog meinen Satz mit dem Groschen rückwirkend auf Bernhard Geyers erste Antwort. Da ist bei mir der Groschen noch nicht gefallen. Inzwischen schon. Ich gebe aber zu, daß der Satz so kling also ob ich es noch nicht verstanden habe.

Ok DeddyH, mein Fehler, sorry, wollte dich nicht ärgern. :wink:


DeddyH 7. Mai 2009 19:38

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
Ach, klarer Fall von Missverständnis :lol:

Dipl Phys Ernst Winter 9. Mai 2009 23:13

Re: Wie ermittelt man die Grenzen mehrdimensionaler Arrays?
 
"Bernhard Geyer"
Zitat:

Wie wäre es damit?
Delphi-Quellcode:
  j := High(a[0]);

[/quote]
Nicht aufgepasst: a[0] gibt's nicht! Muß Heigh(a[1]) heißen


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:23 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